BIG MASSIVE REFACTOR OMG

Ripped out literally everything to simplify the backend as much as
possible.

Some of the code was so horrifically complicated it's insaneeee
This commit is contained in:
2025-09-21 21:31:44 +01:00
parent f8619d3ef7
commit 221afb599b
40 changed files with 512 additions and 1830 deletions

View File

@@ -4,7 +4,6 @@ import (
"context"
"database/sql"
"fmt"
"screenmark/screenmark/.gen/haystack/haystack/enum"
"screenmark/screenmark/.gen/haystack/haystack/model"
. "screenmark/screenmark/.gen/haystack/haystack/table"
@@ -18,248 +17,50 @@ type ImageModel struct {
dbPool *sql.DB
}
type ImageData struct {
model.UserImages
func (m ImageModel) Save(ctx context.Context, name string, image []byte, userID uuid.UUID) error {
saveImageStmt := Image.INSERT(Image.ImageName, Image.Image, Image.UserID).
VALUES(name, image, userID)
Image model.Image
}
type ProcessingImageData struct {
model.UserImagesToProcess
Image model.Image
}
type UserProcessingImage struct {
model.UserImagesToProcess
Image model.Image
}
func (m ImageModel) Process(ctx context.Context, userId uuid.UUID, image model.Image) (model.UserImagesToProcess, error) {
tx, err := m.dbPool.BeginTx(ctx, nil)
if err != nil {
return model.UserImagesToProcess{}, fmt.Errorf("Failed to begin transaction: %w", err)
}
insertImageStmt := Image.
INSERT(Image.ImageName, Image.Image, Image.Description).
VALUES(image.ImageName, image.Image, image.Description).
RETURNING(Image.ID)
insertedImage := model.Image{}
err = insertImageStmt.QueryContext(ctx, tx, &insertedImage)
if err != nil {
return model.UserImagesToProcess{}, fmt.Errorf("Could not insert/query new image. SQL %s: %w", insertImageStmt.DebugSql(), err)
}
stmt := UserImagesToProcess.
INSERT(UserImagesToProcess.UserID, UserImagesToProcess.ImageID).
VALUES(userId, insertedImage.ID).
RETURNING(UserImagesToProcess.AllColumns)
userImage := model.UserImagesToProcess{}
err = stmt.QueryContext(ctx, tx, &userImage)
if err != nil {
return model.UserImagesToProcess{}, fmt.Errorf("Could not insert user_image: %w", err)
}
err = tx.Commit()
return userImage, err
}
func (m ImageModel) GetToProcess(ctx context.Context, imageId uuid.UUID) (UserProcessingImage, error) {
getToProcessStmt := SELECT(UserImagesToProcess.AllColumns, Image.ID, Image.ImageName).
FROM(
UserImagesToProcess.INNER_JOIN(
Image, Image.ID.EQ(UserImagesToProcess.ImageID),
),
).
WHERE(UserImagesToProcess.ID.EQ(UUID(imageId)))
images := []UserProcessingImage{}
err := getToProcessStmt.QueryContext(ctx, m.dbPool, &images)
if len(images) != 1 {
return UserProcessingImage{}, fmt.Errorf("Expected 1, got %d\n", len(images))
}
return images[0], err
}
func (m ImageModel) GetToProcessWithData(ctx context.Context, imageId uuid.UUID) (ProcessingImageData, error) {
stmt := SELECT(UserImagesToProcess.AllColumns, Image.AllColumns).
FROM(
UserImagesToProcess.INNER_JOIN(
Image, Image.ID.EQ(UserImagesToProcess.ImageID),
),
).WHERE(UserImagesToProcess.ID.EQ(UUID(imageId)))
images := []ProcessingImageData{}
err := stmt.QueryContext(ctx, m.dbPool, &images)
if len(images) != 1 {
return ProcessingImageData{}, fmt.Errorf("Expected 1, got %d\n", len(images))
}
return images[0], err
}
func (m ImageModel) FinishProcessing(ctx context.Context, imageId uuid.UUID) (model.UserImages, error) {
imageToProcess, err := m.GetToProcess(ctx, imageId)
if err != nil {
return model.UserImages{}, err
}
tx, err := m.dbPool.Begin()
if err != nil {
return model.UserImages{}, err
}
insertImageStmt := UserImages.
INSERT(UserImages.UserID, UserImages.ImageID).
VALUES(imageToProcess.UserID, imageToProcess.ImageID).
RETURNING(UserImages.ID, UserImages.UserID, UserImages.ImageID)
userImage := model.UserImages{}
err = insertImageStmt.QueryContext(ctx, tx, &userImage)
if err != nil {
return model.UserImages{}, err
}
// Hacky. Update the status before removing so we can get our regular triggers
// to work.
updateStatusStmt := UserImagesToProcess.
UPDATE(UserImagesToProcess.Status).
SET(model.Progress_Complete).
WHERE(UserImagesToProcess.ID.EQ(UUID(imageToProcess.ID)))
_, err = updateStatusStmt.ExecContext(ctx, tx)
if err != nil {
return model.UserImages{}, err
}
// TODO:
// We cannot delete the image to process because our events rely on it.
// This indicates our DB structure with the two tables might need some adjusting.
// Or re-doing all together perhaps.
// (switching to a one table (user_images) could work)
// But for now, we can just not delete the images to process and set them to complete
// removeProcessingStmt := UserImagesToProcess.
// DELETE().
// WHERE(UserImagesToProcess.ID.EQ(UUID(imageToProcess.ID)))
//
// _, err = removeProcessingStmt.ExecContext(ctx, tx)
// if err != nil {
// return model.UserImages{}, err
// }
err = tx.Commit()
return userImage, err
}
func (m ImageModel) GetImageToProcessID(ctx context.Context, imageID uuid.UUID) (uuid.UUID, error) {
getImageToProcessIDStmt := UserImagesToProcess.
SELECT(UserImagesToProcess.ID).
WHERE(UserImagesToProcess.ImageID.EQ(UUID(imageID)))
imageToProcess := model.UserImagesToProcess{}
err := getImageToProcessIDStmt.QueryContext(ctx, m.dbPool, &imageToProcess)
return imageToProcess.ID, err
}
func (m ImageModel) SetNotStarted(ctx context.Context, processingImageId uuid.UUID) error {
startProcessingStmt := UserImagesToProcess.
UPDATE(UserImagesToProcess.Status).
SET(model.Progress_NotStarted).
WHERE(UserImagesToProcess.ID.EQ(UUID(processingImageId)))
_, err := startProcessingStmt.ExecContext(ctx, m.dbPool)
_, err := saveImageStmt.ExecContext(ctx, m.dbPool)
return err
}
func (m ImageModel) StartProcessing(ctx context.Context, processingImageId uuid.UUID) error {
startProcessingStmt := UserImagesToProcess.
UPDATE(UserImagesToProcess.Status).
SET(model.Progress_InProgress).
WHERE(UserImagesToProcess.ID.EQ(UUID(processingImageId)))
_, err := startProcessingStmt.ExecContext(ctx, m.dbPool)
return err
}
func (m ImageModel) Get(ctx context.Context, imageId uuid.UUID) (model.Image, error) {
getImageStmt := Image.SELECT(Image.AllColumns).
WHERE(Image.ID.EQ(UUID(imageId)))
func (m ImageModel) Get(ctx context.Context, imageID uuid.UUID) (model.Image, bool, error) {
getImageStmt := Image.SELECT(Image.AllColumns.Except(Image.Image)).WHERE(Image.ID.EQ(UUID(imageID)))
image := model.Image{}
err := getImageStmt.QueryContext(ctx, m.dbPool, &image)
return image, err
return image, err != qrm.ErrNoRows, err
}
func (m ImageModel) GetProcessing(ctx context.Context, userId uuid.UUID) ([]UserProcessingImage, error) {
getProcessingStmt := SELECT(UserImagesToProcess.AllColumns, Image.ID, Image.ImageName).
FROM(
UserImagesToProcess.INNER_JOIN(
Image, Image.ID.EQ(UserImagesToProcess.ImageID),
),
).WHERE(
UserImagesToProcess.UserID.EQ(UUID(userId)).
AND(UserImagesToProcess.Status.NOT_EQ(enum.Progress.Complete)),
)
func (m ImageModel) Update(ctx context.Context, image model.Image) (model.Image, error) {
updateImageStmt := Image.UPDATE(Image.MutableColumns.Except(Image.Image)).
MODEL(image).
WHERE(Image.ID.EQ(UUID(image.ID))).
RETURNING(Image.AllColumns.Except(Image.Image))
images := []UserProcessingImage{}
err := getProcessingStmt.QueryContext(ctx, m.dbPool, &images)
updatedImage := model.Image{}
err := updateImageStmt.QueryContext(ctx, m.dbPool, &updatedImage)
return images, err
return updatedImage, err
}
func (m ImageModel) AddDescription(ctx context.Context, imageId uuid.UUID, description string) error {
updateImageStmt := Image.UPDATE(Image.Description).
SET(description).
WHERE(Image.ID.EQ(UUID(imageId)))
func (m ImageModel) Delete(ctx context.Context, imageID, userID uuid.UUID) (bool, error) {
deleteImageStmt := Image.DELETE().WHERE(Image.ID.EQ(UUID(imageID)).AND(Image.UserID.EQ(UUID(userID))))
_, err := updateImageStmt.ExecContext(ctx, m.dbPool)
r, err := deleteImageStmt.ExecContext(ctx, m.dbPool)
if err != nil {
return false, fmt.Errorf("deleting image: %w", err)
}
return err
}
rowsAffected, err := r.RowsAffected()
if err != nil {
return false, fmt.Errorf("unreachable: %w", err)
}
func (m ImageModel) DeleteUserImage(ctx context.Context, imageID uuid.UUID) error {
deleteImageStmt := UserImages.DELETE().
WHERE(UserImages.ImageID.EQ(UUID(imageID)))
_, err := deleteImageStmt.ExecContext(ctx, m.dbPool)
return err
}
func (m ImageModel) Delete(ctx context.Context, imageID uuid.UUID) error {
deleteImageStmt := Image.DELETE().
WHERE(Image.ID.EQ(UUID(imageID)))
_, err := deleteImageStmt.ExecContext(ctx, m.dbPool)
return err
}
func (m ImageModel) IsUserAuthorized(ctx context.Context, imageId uuid.UUID, userId uuid.UUID) bool {
getImageUserId := UserImages.SELECT(UserImages.UserID).WHERE(UserImages.ImageID.EQ(UUID(imageId)))
getProcessingImageUserId := UserImagesToProcess.SELECT(UserImagesToProcess.UserID).WHERE(UserImagesToProcess.ImageID.EQ(UUID(imageId)))
userImage := model.UserImages{}
userProcessingImage := model.UserImagesToProcess{}
err1 := getImageUserId.QueryContext(ctx, m.dbPool, &userImage)
err2 := getProcessingImageUserId.QueryContext(ctx, m.dbPool, &userProcessingImage)
return (err1 == nil || err1 == qrm.ErrNoRows) && (err2 == nil || err2 == qrm.ErrNoRows) && (userImage.UserID.String() == userId.String() || userProcessingImage.UserID.String() == userId.String())
return rowsAffected > 0, nil
}
func NewImageModel(db *sql.DB) ImageModel {

View File

@@ -3,7 +3,6 @@ package models
import (
"context"
"database/sql"
"fmt"
"screenmark/screenmark/.gen/haystack/haystack/model"
. "screenmark/screenmark/.gen/haystack/haystack/table"
@@ -12,22 +11,18 @@ import (
"github.com/google/uuid"
)
type ListModel struct {
type StackModel struct {
dbPool *sql.DB
}
type ListWithItems struct {
model.Lists
type StackWithItems struct {
model.Stacks
Schema struct {
model.Schemas
SchemaItems []model.SchemaItems
}
SchemaItems []model.SchemaItems
}
type ImageWithSchema struct {
model.ImageLists
model.ImageStacks
Items []model.ImageSchemaItems
}
@@ -41,35 +36,33 @@ type IDValue struct {
// SELECT for lists
// ========================================
func (m ListModel) List(ctx context.Context, userId uuid.UUID) ([]ListWithItems, error) {
getListsWithItems := SELECT(
Lists.AllColumns,
Schemas.AllColumns,
func (m StackModel) List(ctx context.Context, userId uuid.UUID) ([]StackWithItems, error) {
getStacksWithItems := SELECT(
Stacks.AllColumns,
SchemaItems.AllColumns,
).
FROM(
Lists.
INNER_JOIN(Schemas, Schemas.ListID.EQ(Lists.ID)).
INNER_JOIN(SchemaItems, SchemaItems.SchemaID.EQ(Schemas.ID)),
Stacks.
INNER_JOIN(SchemaItems, SchemaItems.StackID.EQ(Stacks.ID)),
).
WHERE(Lists.UserID.EQ(UUID(userId)))
WHERE(Stacks.UserID.EQ(UUID(userId)))
lists := []ListWithItems{}
err := getListsWithItems.QueryContext(ctx, m.dbPool, &lists)
lists := []StackWithItems{}
err := getStacksWithItems.QueryContext(ctx, m.dbPool, &lists)
return lists, err
}
func (m ListModel) ListItems(ctx context.Context, listID uuid.UUID) ([]ImageWithSchema, error) {
func (m StackModel) ListItems(ctx context.Context, listID uuid.UUID) ([]ImageWithSchema, error) {
getListItems := SELECT(
ImageLists.AllColumns,
ImageStacks.AllColumns,
ImageSchemaItems.AllColumns,
).
FROM(
ImageLists.
INNER_JOIN(ImageSchemaItems, ImageSchemaItems.ImageID.EQ(ImageLists.ImageID)),
ImageStacks.
INNER_JOIN(ImageSchemaItems, ImageSchemaItems.ImageID.EQ(ImageStacks.ImageID)),
).
WHERE(ImageLists.ListID.EQ(UUID(listID)))
WHERE(ImageStacks.StackID.EQ(UUID(listID)))
listItems := make([]ImageWithSchema, 0)
err := getListItems.QueryContext(ctx, m.dbPool, &listItems)
@@ -77,174 +70,45 @@ func (m ListModel) ListItems(ctx context.Context, listID uuid.UUID) ([]ImageWith
return listItems, err
}
// ========================================
// SELECT for specific items
// ========================================
func (m StackModel) Get(ctx context.Context, listID uuid.UUID) (model.Stacks, error) {
getStackStmt := Stacks.SELECT(Stacks.AllColumns).WHERE(Stacks.ID.EQ(UUID(listID)))
func (m ListModel) GetProcessing(ctx context.Context, processingListID uuid.UUID) (model.ProcessingLists, error) {
getProcessingListStmt := ProcessingLists.
SELECT(ProcessingLists.AllColumns).
WHERE(ProcessingLists.ID.EQ(UUID(processingListID)))
stack := model.Stacks{}
err := getStackStmt.QueryContext(ctx, m.dbPool, &stack)
list := model.ProcessingLists{}
err := getProcessingListStmt.QueryContext(ctx, m.dbPool, &list)
return list, err
}
func (m ListModel) GetToProcess(ctx context.Context, listID uuid.UUID) (model.ProcessingLists, error) {
getToProcessStmt := ProcessingLists.
SELECT(ProcessingLists.AllColumns).
WHERE(ProcessingLists.ID.EQ(UUID(listID)))
stack := []model.ProcessingLists{}
err := getToProcessStmt.QueryContext(ctx, m.dbPool, &stack)
if len(stack) != 1 {
return model.ProcessingLists{}, fmt.Errorf("Expected 1, got %d\n", len(stack))
}
return stack[0], err
}
// ========================================
// UPDATE
// ========================================
func (m ListModel) StartProcessing(ctx context.Context, processingListID uuid.UUID) error {
startProcessingStmt := ProcessingLists.
UPDATE(ProcessingLists.Status).
SET(model.Progress_InProgress).
WHERE(ProcessingLists.ID.EQ(UUID(processingListID)))
_, err := startProcessingStmt.ExecContext(ctx, m.dbPool)
return err
}
func (m ListModel) EndProcessing(ctx context.Context, processingListID uuid.UUID) error {
startProcessingStmt := ProcessingLists.
UPDATE(ProcessingLists.Status).
SET(model.Progress_Complete).
WHERE(ProcessingLists.ID.EQ(UUID(processingListID)))
_, err := startProcessingStmt.ExecContext(ctx, m.dbPool)
return err
return stack, err
}
// ========================================
// INSERT methods
// ========================================
func (m ListModel) Save(ctx context.Context, userId uuid.UUID, name string, description string, schemaItems []model.SchemaItems) (ListWithItems, error) {
tx, err := m.dbPool.BeginTx(ctx, nil)
func (m StackModel) Save(ctx context.Context, userID uuid.UUID, name string, description string) (model.Stacks, error) {
saveListStmt := Stacks.
INSERT(Stacks.UserID, Stacks.Name, Stacks.Description).
VALUES(userID, name, description).
RETURNING(Stacks.ID, Stacks.UserID, Stacks.Name, Stacks.Description, Stacks.CreatedAt)
stmt := Lists.INSERT(Lists.UserID, Lists.Name, Lists.Description).
VALUES(userId, name, description).
RETURNING(Lists.ID, Lists.Name, Lists.Description)
list := model.Stacks{}
err := saveListStmt.QueryContext(ctx, m.dbPool, &list)
newList := model.Lists{}
err = stmt.QueryContext(ctx, tx, &newList)
if err != nil {
tx.Rollback()
return ListWithItems{}, fmt.Errorf("Could not save new list. %s", err)
}
insertSchemaStmt := Schemas.INSERT(Schemas.ListID).
VALUES(newList.ID).
RETURNING(Schemas.ID)
newSchema := model.Schemas{}
err = insertSchemaStmt.QueryContext(ctx, tx, &newSchema)
if err != nil {
tx.Rollback()
return ListWithItems{}, fmt.Errorf("Could not save new schema. %s", err)
}
// This is very interesting...
for i := range schemaItems {
schemaItems[i].SchemaID = newSchema.ID
}
insertSchemaItemsStmt := SchemaItems.INSERT(SchemaItems.Item, SchemaItems.Value, SchemaItems.Description, SchemaItems.SchemaID).
MODELS(schemaItems)
_, err = insertSchemaItemsStmt.ExecContext(ctx, tx)
if err != nil {
tx.Rollback()
return ListWithItems{}, fmt.Errorf("Could not save schema items. %s", err)
}
err = tx.Commit()
if err != nil {
return ListWithItems{}, fmt.Errorf("Could not commit transaction. %s", err)
}
getListAndItems := SELECT(Lists.AllColumns, Schemas.AllColumns, SchemaItems.AllColumns).
FROM(
Lists.
INNER_JOIN(Schemas, Schemas.ListID.EQ(Lists.ID)).
INNER_JOIN(SchemaItems, SchemaItems.SchemaID.EQ(Schemas.ID)),
).
WHERE(Lists.ID.EQ(UUID(newList.ID)))
listWithItems := ListWithItems{}
err = getListAndItems.QueryContext(ctx, m.dbPool, &listWithItems)
return listWithItems, err
return list, err
}
func (m ListModel) SaveInto(ctx context.Context, listID uuid.UUID, imageID uuid.UUID, schemaValues []IDValue) error {
tx, err := m.dbPool.BeginTx(ctx, nil)
if err != nil {
return err
}
func (m StackModel) SaveItems(ctx context.Context, items []model.SchemaItems) error {
saveItemsStmt := SchemaItems.INSERT(SchemaItems.AllColumns).MODELS(items)
var imageList model.ImageLists
stmt := ImageLists.INSERT(ImageLists.ListID, ImageLists.ImageID).
VALUES(listID, imageID).
RETURNING(ImageLists.ID)
_, err := saveItemsStmt.ExecContext(ctx, m.dbPool)
err = stmt.QueryContext(ctx, m.dbPool, &imageList)
if err != nil {
tx.Rollback()
return fmt.Errorf("Could not insert new list. %s", err)
}
imageSchemaItems := make([]model.ImageSchemaItems, len(schemaValues))
for i, v := range schemaValues {
parsedId, err := uuid.Parse(v.ID)
if err != nil {
return err
}
imageSchemaItems[i].SchemaItemID = parsedId
imageSchemaItems[i].ImageID = imageList.ID
imageSchemaItems[i].Value = &v.Value
}
insertSchemaItemsStmt := ImageSchemaItems.
INSERT(ImageSchemaItems.Value, ImageSchemaItems.SchemaItemID, ImageSchemaItems.ImageID).
MODELS(imageSchemaItems)
_, err = insertSchemaItemsStmt.ExecContext(ctx, tx)
if err != nil {
tx.Rollback()
return fmt.Errorf("Could not insert schema items. %s", err)
}
err = tx.Commit()
return err
}
func (m ListModel) SaveProcessing(ctx context.Context, userID uuid.UUID, title string, fields string) error {
insertListToProcess := ProcessingLists.
INSERT(ProcessingLists.UserID, ProcessingLists.Title, ProcessingLists.Fields).
VALUES(userID, title, fields)
func (m StackModel) SaveImage(ctx context.Context, imageID uuid.UUID, stackID uuid.UUID) error {
saveImageStmt := ImageStacks.
INSERT(ImageStacks.ImageID, ImageStacks.StackID).
VALUES(imageID, stackID)
_, err := insertListToProcess.ExecContext(ctx, m.dbPool)
_, err := saveImageStmt.ExecContext(ctx, m.dbPool)
return err
}
@@ -253,11 +117,11 @@ func (m ListModel) SaveProcessing(ctx context.Context, userID uuid.UUID, title s
// DELETE methods
// ========================================
func (m ListModel) DeleteImage(ctx context.Context, listID uuid.UUID, imageID uuid.UUID) error {
deleteImageListStmt := ImageLists.DELETE().
func (m StackModel) DeleteImage(ctx context.Context, listID uuid.UUID, imageID uuid.UUID) error {
deleteImageListStmt := ImageStacks.DELETE().
WHERE(
ImageLists.ListID.EQ(UUID(listID)).
AND(ImageLists.ImageID.EQ(UUID(imageID))),
ImageStacks.StackID.EQ(UUID(listID)).
AND(ImageStacks.ImageID.EQ(UUID(imageID))),
)
_, err := deleteImageListStmt.ExecContext(ctx, m.dbPool)
@@ -265,60 +129,14 @@ func (m ListModel) DeleteImage(ctx context.Context, listID uuid.UUID, imageID uu
return err
}
func (m ListModel) Delete(ctx context.Context, listID uuid.UUID, userID uuid.UUID) error {
// First verify the list belongs to the user
checkOwnershipStmt := Lists.
SELECT(Lists.ID).
WHERE(Lists.ID.EQ(UUID(listID)).AND(Lists.UserID.EQ(UUID(userID))))
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))))
var existingList model.Lists
err := checkOwnershipStmt.QueryContext(ctx, m.dbPool, &existingList)
if err != nil {
return fmt.Errorf("could not verify list ownership: %w", err)
}
_, err := deleteStackStmt.ExecContext(ctx, m.dbPool)
// Start a transaction to ensure all deletions happen atomically
tx, err := m.dbPool.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("could not start transaction: %w", err)
}
defer tx.Rollback()
// Delete in reverse order of dependencies:
// 1. Delete schema items first
deleteSchemaItemsStmt := SchemaItems.DELETE().
WHERE(SchemaItems.SchemaID.IN(
Schemas.SELECT(Schemas.ID).
WHERE(Schemas.ListID.EQ(UUID(listID))),
))
_, err = deleteSchemaItemsStmt.ExecContext(ctx, tx)
if err != nil {
return fmt.Errorf("could not delete schema items: %w", err)
}
// 2. Delete schemas
deleteSchemasStmt := Schemas.DELETE().WHERE(Schemas.ListID.EQ(UUID(listID)))
_, err = deleteSchemasStmt.ExecContext(ctx, tx)
if err != nil {
return fmt.Errorf("could not delete schemas: %w", err)
}
// 3. Delete the list itself
deleteListStmt := Lists.DELETE().WHERE(Lists.ID.EQ(UUID(listID)))
_, err = deleteListStmt.ExecContext(ctx, tx)
if err != nil {
return fmt.Errorf("could not delete list: %w", err)
}
// Commit the transaction
err = tx.Commit()
if err != nil {
return fmt.Errorf("could not commit transaction: %w", err)
}
return nil
return err
}
func NewListModel(db *sql.DB) ListModel {
return ListModel{dbPool: db}
func NewListModel(db *sql.DB) StackModel {
return StackModel{dbPool: db}
}

View File

@@ -49,28 +49,20 @@ func (m UserModel) Save(ctx context.Context, user model.Users) (model.Users, err
}
type UserImageWithImage struct {
model.UserImages
Image struct {
model.Image
ImageLists []model.ImageLists
}
model.Image
ImageStacks []model.ImageStacks
}
func (m UserModel) GetUserImages(ctx context.Context, userId uuid.UUID) ([]UserImageWithImage, error) {
getUserImagesStmt := SELECT(
UserImages.AllColumns,
Image.ID,
Image.ImageName,
Image.Description,
ImageLists.AllColumns,
Image.AllColumns.Except(Image.Image),
ImageStacks.AllColumns,
).
FROM(
UserImages.
INNER_JOIN(Image, Image.ID.EQ(UserImages.ImageID)).
LEFT_JOIN(ImageLists, ImageLists.ImageID.EQ(UserImages.ImageID)),
Image.
LEFT_JOIN(ImageStacks, ImageStacks.ImageID.EQ(ImageStacks.ID)),
).
WHERE(UserImages.UserID.EQ(UUID(userId)))
WHERE(Image.UserID.EQ(UUID(userId)))
userImages := []UserImageWithImage{}
err := getUserImagesStmt.QueryContext(ctx, m.dbPool, &userImages)
@@ -79,16 +71,12 @@ func (m UserModel) GetUserImages(ctx context.Context, userId uuid.UUID) ([]UserI
}
type ListsWithImages struct {
model.Lists
model.Stacks
Schema struct {
model.Schemas
SchemaItems []model.SchemaItems
}
SchemaItems []model.SchemaItems
Images []struct {
model.ImageLists
model.ImageStacks
Items []model.ImageSchemaItems
}
@@ -96,20 +84,18 @@ type ListsWithImages struct {
func (m UserModel) ListWithImages(ctx context.Context, userId uuid.UUID) ([]ListsWithImages, error) {
stmt := SELECT(
Lists.AllColumns,
ImageLists.AllColumns,
Schemas.AllColumns,
Stacks.AllColumns,
ImageStacks.AllColumns,
SchemaItems.AllColumns,
ImageSchemaItems.AllColumns,
).
FROM(
Lists.
INNER_JOIN(Schemas, Schemas.ListID.EQ(Lists.ID)).
INNER_JOIN(SchemaItems, SchemaItems.SchemaID.EQ(Schemas.ID)).
LEFT_JOIN(ImageLists, ImageLists.ListID.EQ(Lists.ID)).
LEFT_JOIN(ImageSchemaItems, ImageSchemaItems.ImageID.EQ(ImageLists.ID)),
Stacks.
INNER_JOIN(SchemaItems, SchemaItems.StackID.EQ(Stacks.ID)).
LEFT_JOIN(ImageStacks, ImageStacks.StackID.EQ(Stacks.ID)).
LEFT_JOIN(ImageSchemaItems, ImageSchemaItems.ImageID.EQ(ImageStacks.ID)),
).
WHERE(Lists.UserID.EQ(UUID(userId)))
WHERE(Stacks.UserID.EQ(UUID(userId)))
lists := []ListsWithImages{}
err := stmt.QueryContext(ctx, m.dbPool, &lists)