From ef6253f896e604254b48a39755a24a4420ffd35e Mon Sep 17 00:00:00 2001
From: Janne Mareike Koschinski <janne@kuschku.de>
Date: Thu, 26 May 2022 02:19:28 +0200
Subject: [PATCH] fix: improve datatypes and sql types

---
 backend/resize.go                           |  8 +------
 frontend/errors.go                          |  3 ++-
 frontend/migrations/001_images.up.sql       |  1 -
 frontend/migrations/002_albums.up.sql       | 12 +++++-----
 frontend/migrations/003_album_images.up.sql | 10 ++++----
 frontend/page_album_detail.go               | 19 ++++++++-------
 frontend/page_image_detail.go               | 14 +++++------
 frontend/page_image_list.go                 | 26 ++++++++++-----------
 frontend/page_upload.go                     | 22 ++++++++++-------
 {frontend => shared}/model.go               | 21 +++++++++++++++--
 shared/types.go                             | 22 -----------------
 11 files changed, 76 insertions(+), 82 deletions(-)
 rename {frontend => shared}/model.go (58%)
 delete mode 100644 shared/types.go

diff --git a/backend/resize.go b/backend/resize.go
index 005f5b2..2ede626 100644
--- a/backend/resize.go
+++ b/backend/resize.go
@@ -30,7 +30,7 @@ func ResizeImage(env ProcessingEnvironment, imageId string) []error {
 	trackTimeSince(imageProcessDurationRead, startRead)
 
 	log.Printf("launching resize goroutines for %s", imageId)
-	errors := runMany(len(env.Config.Sizes), func(index int) error {
+	return runMany(len(env.Config.Sizes), func(index int) error {
 		definition := env.Config.Sizes[index]
 		path := filepath.Join(env.Config.TargetFolder, fmt.Sprintf("%s%s", imageId, definition.Suffix))
 		startClone := time.Now().UTC()
@@ -61,10 +61,4 @@ func ResizeImage(env ProcessingEnvironment, imageId string) []error {
 		log.Printf("done with image for %s in %v", imageId, definition)
 		return nil
 	})
-	if len(errors) == 0 {
-		if _, err = env.Database.Exec("UPDATE images SET metadata = $2 WHERE id = $1", imageId, originalImage.ParseMetadata()); err != nil {
-			return []error{err}
-		}
-	}
-	return errors
 }
diff --git a/frontend/errors.go b/frontend/errors.go
index e8d868d..23e4ffb 100644
--- a/frontend/errors.go
+++ b/frontend/errors.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"git.kuschku.de/justjanne/imghost/shared"
 	"log"
 	"net/http"
 	"net/url"
@@ -8,7 +9,7 @@ import (
 
 type ErrorData struct {
 	Code  int
-	User  UserInfo
+	User  shared.UserInfo
 	URL   *url.URL
 	Error error
 }
diff --git a/frontend/migrations/001_images.up.sql b/frontend/migrations/001_images.up.sql
index 80c6695..cfe987b 100644
--- a/frontend/migrations/001_images.up.sql
+++ b/frontend/migrations/001_images.up.sql
@@ -6,7 +6,6 @@ create table if not exists images
     description   text  default ''   not null,
     original_name text  default ''   not null,
     type          text               not null,
-    metadata      jsonb default '{}' not null,
     created_at    timestamp          not null,
     updated_at    timestamp          not null
 );
diff --git a/frontend/migrations/002_albums.up.sql b/frontend/migrations/002_albums.up.sql
index cf94648..08d57e6 100644
--- a/frontend/migrations/002_albums.up.sql
+++ b/frontend/migrations/002_albums.up.sql
@@ -1,11 +1,11 @@
 create table if not exists albums
 (
-    id          text not null primary key,
-    owner       text,
-    title       text,
-    description text,
-    created_at  timestamp,
-    updated_at  timestamp
+    id          text            not null primary key,
+    owner       text            not null,
+    title       text default '' not null,
+    description text default '' not null,
+    created_at  timestamp       not null,
+    updated_at  timestamp       not null
 );
 
 create index if not exists albums_owner_index
diff --git a/frontend/migrations/003_album_images.up.sql b/frontend/migrations/003_album_images.up.sql
index c9b97bb..ae7cc93 100644
--- a/frontend/migrations/003_album_images.up.sql
+++ b/frontend/migrations/003_album_images.up.sql
@@ -1,16 +1,16 @@
 create table if not exists album_images
 (
-    album       text not null
+    album       text            not null
         constraint album_images_albums_id_fk
             references albums
             on update cascade on delete cascade,
-    image       text not null
+    image       text            not null
         constraint album_images_images_id_fk
             references images
             on update cascade on delete cascade,
-    title       text,
-    description text,
-    position    integer,
+    title       text default '' not null,
+    description text default '' not null,
+    position    integer         not null,
     constraint album_images_image_album_pk
         primary key (image, album)
 );
diff --git a/frontend/page_album_detail.go b/frontend/page_album_detail.go
index 9ee24c0..cc96f19 100644
--- a/frontend/page_album_detail.go
+++ b/frontend/page_album_detail.go
@@ -1,28 +1,29 @@
 package main
 
 import (
+	"git.kuschku.de/justjanne/imghost/shared"
 	"net/http"
 	"path"
 )
 
 type AlbumDetailData struct {
-	User   UserInfo
-	Album  Album
+	User   shared.UserInfo
+	Album  shared.Album
 	IsMine bool
 }
 
 func pageAlbumDetail(env PageEnvironment) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		user := parseUser(r)
+		user := shared.ParseUser(r)
 
 		_, albumId := path.Split(r.URL.Path)
 		result, err := env.Database.Query(`
 			SELECT
 				id,
 				owner,
-				coalesce(title,  ''),
-				coalesce(description, ''),
-        		coalesce(created_at, to_timestamp(0))
+				title,
+				description,
+        		created_at
 			FROM albums
 			WHERE id = $1
 			`, albumId)
@@ -31,7 +32,7 @@ func pageAlbumDetail(env PageEnvironment) http.Handler {
 			return
 		}
 
-		var info Album
+		var info shared.Album
 		if result.Next() {
 			var owner string
 			err := result.Scan(&info.Id, &owner, &info.Title, &info.Description, &info.CreatedAt)
@@ -48,7 +49,7 @@ func pageAlbumDetail(env PageEnvironment) http.Handler {
 				position
 			FROM album_images
 			WHERE album = $1
-			ORDER BY position ASC
+			ORDER BY position
 			`, albumId)
 			if err != nil {
 				formatError(w, ErrorData{http.StatusInternalServerError, user, r.URL, err}, "html")
@@ -56,7 +57,7 @@ func pageAlbumDetail(env PageEnvironment) http.Handler {
 			}
 
 			for result.Next() {
-				var image AlbumImage
+				var image shared.AlbumImage
 				err := result.Scan(&image.Id, &owner, &image.Title, &image.Description, &image.Position)
 				if err != nil {
 					formatError(w, ErrorData{http.StatusInternalServerError, user, r.URL, err}, "html")
diff --git a/frontend/page_image_detail.go b/frontend/page_image_detail.go
index 2f2fa1e..97f59ad 100644
--- a/frontend/page_image_detail.go
+++ b/frontend/page_image_detail.go
@@ -10,7 +10,7 @@ import (
 )
 
 type ImageDetailData struct {
-	User    UserInfo
+	User    shared.UserInfo
 	Image   shared.Image
 	IsMine  bool
 	BaseUrl string
@@ -18,18 +18,18 @@ type ImageDetailData struct {
 
 func pageImageDetail(env PageEnvironment) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		user := parseUser(r)
+		user := shared.ParseUser(r)
 		_, imageId := path.Split(r.URL.Path)
 
 		result, err := env.Database.Query(`
 			SELECT
 				id,
 				owner,
-				coalesce(title,  ''),
-				coalesce(description, ''),
-        		coalesce(created_at, to_timestamp(0)),
-				coalesce(original_name, ''),
-				coalesce(type, '')
+				title,
+				description,
+				created_at,
+				original_name,
+				type
 			FROM images
 			WHERE id = $1
 			`, imageId)
diff --git a/frontend/page_image_list.go b/frontend/page_image_list.go
index 9a68e96..583e3de 100644
--- a/frontend/page_image_list.go
+++ b/frontend/page_image_list.go
@@ -9,7 +9,7 @@ import (
 )
 
 type ImageListData struct {
-	User     UserInfo
+	User     shared.UserInfo
 	Images   []shared.Image
 	Previous int64
 	Current  int64
@@ -18,16 +18,16 @@ type ImageListData struct {
 
 const PageSize = 30
 
-func paginateImageListQuery(env PageEnvironment, user UserInfo, offset int64, pageSize int) (*sql.Rows, error) {
+func paginateImageListQuery(env PageEnvironment, user shared.UserInfo, offset int64, pageSize int) (*sql.Rows, error) {
 	if offset == 0 {
 		return env.Database.Query(`
 			SELECT
 				id,
-				coalesce(title,  ''),
-				coalesce(description, ''),
-        		coalesce(created_at, to_timestamp(0)),
-				coalesce(original_name, ''),
-				coalesce(type, '')
+				title,
+				description,
+        		created_at,
+				original_name,
+				type
 			FROM images
 			WHERE owner = $1
 			ORDER BY created_at DESC
@@ -37,11 +37,11 @@ func paginateImageListQuery(env PageEnvironment, user UserInfo, offset int64, pa
 		return env.Database.Query(`
 			SELECT
 				id,
-				coalesce(title,  ''),
-				coalesce(description, ''),
-        		coalesce(created_at, to_timestamp(0)),
-				coalesce(original_name, ''),
-				coalesce(type, '')
+				title,
+				description,
+        		created_at,
+				original_name,
+				type
 			FROM images
 			WHERE owner = $1
 			ORDER BY created_at DESC
@@ -53,7 +53,7 @@ func paginateImageListQuery(env PageEnvironment, user UserInfo, offset int64, pa
 
 func pageImageList(ctx PageEnvironment) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		user := parseUser(r)
+		user := shared.ParseUser(r)
 		_, page := path.Split(r.URL.Path)
 		var pageNumber int64
 		pageNumber, err := strconv.ParseInt(page, 10, 64)
diff --git a/frontend/page_upload.go b/frontend/page_upload.go
index 53218aa..562a401 100644
--- a/frontend/page_upload.go
+++ b/frontend/page_upload.go
@@ -17,7 +17,7 @@ import (
 
 type UploadData struct {
 	BaseUrl string
-	User    UserInfo
+	User    shared.UserInfo
 }
 
 func detectMimeType(path string) (string, error) {
@@ -35,11 +35,13 @@ func detectMimeType(path string) (string, error) {
 	return http.DetectContentType(buffer), nil
 }
 
-func generateId() string {
+func generateId() (string, error) {
 	buffer := make([]byte, 4)
-	rand.Read(buffer)
+	if _, err := rand.Read(buffer); err != nil {
+		return "", err
+	}
 
-	return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(buffer)
+	return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(buffer), nil
 }
 
 func writeBody(reader io.ReadCloser, path string) error {
@@ -57,11 +59,13 @@ func writeBody(reader io.ReadCloser, path string) error {
 }
 
 func createImage(config *shared.Config, body io.ReadCloser, fileHeader *multipart.FileHeader) (shared.Image, error) {
-	id := generateId()
+	id, err := generateId()
+	if err != nil {
+		return shared.Image{}, err
+	}
 	path := filepath.Join(config.SourceFolder, id)
 
-	err := writeBody(body, path)
-	if err != nil {
+	if err := writeBody(body, path); err != nil {
 		return shared.Image{}, err
 	}
 
@@ -82,7 +86,7 @@ func createImage(config *shared.Config, body io.ReadCloser, fileHeader *multipar
 func pageUpload(env PageEnvironment) http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		if r.Method == "POST" {
-			user := parseUser(r)
+			user := shared.ParseUser(r)
 
 			err := r.ParseMultipartForm(32 << 20)
 			if err != nil {
@@ -135,7 +139,7 @@ func pageUpload(env PageEnvironment) http.Handler {
 			}
 			return
 		} else {
-			user := parseUser(r)
+			user := shared.ParseUser(r)
 			if err := formatTemplate(w, "upload.html", UploadData{
 				env.Config.BaseUrl,
 				user,
diff --git a/frontend/model.go b/shared/model.go
similarity index 58%
rename from frontend/model.go
rename to shared/model.go
index 8186f60..2df5c59 100644
--- a/frontend/model.go
+++ b/shared/model.go
@@ -1,6 +1,7 @@
-package main
+package shared
 
 import (
+	"git.kuschku.de/justjanne/imghost/imgconv"
 	"net/http"
 	"strings"
 	"time"
@@ -13,7 +14,7 @@ type UserInfo struct {
 	Roles []string
 }
 
-func parseUser(r *http.Request) UserInfo {
+func ParseUser(r *http.Request) UserInfo {
 	return UserInfo{
 		r.Header.Get("X-Auth-Subject"),
 		r.Header.Get("X-Auth-Username"),
@@ -31,6 +32,22 @@ func (info UserInfo) HasRole(role string) bool {
 	return false
 }
 
+type Result struct {
+	Id       string           `json:"id"`
+	Success  bool             `json:"success"`
+	Errors   []string         `json:"errors"`
+	Metadata imgconv.Metadata `json:"metadata"`
+}
+
+type Image struct {
+	Id           string `json:"id"`
+	Title        string
+	Description  string
+	CreatedAt    time.Time
+	OriginalName string
+	MimeType     string `json:"mimeType"`
+}
+
 type AlbumImage struct {
 	Id          string
 	Title       string
diff --git a/shared/types.go b/shared/types.go
deleted file mode 100644
index 017ce8f..0000000
--- a/shared/types.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package shared
-
-import (
-	"git.kuschku.de/justjanne/imghost/imgconv"
-	"time"
-)
-
-type Image struct {
-	Id           string `json:"id"`
-	Title        string
-	Description  string
-	CreatedAt    time.Time
-	OriginalName string
-	MimeType     string `json:"mimeType"`
-}
-
-type Result struct {
-	Id       string           `json:"id"`
-	Success  bool             `json:"success"`
-	Errors   []string         `json:"errors"`
-	Metadata imgconv.Metadata `json:"metadata"`
-}
-- 
GitLab