Add composers
This commit is contained in:
@@ -18,7 +18,7 @@ func InitDatabase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto migrate the schema
|
// Auto migrate the schema
|
||||||
err = DB.AutoMigrate(&models.User{}, &models.Sheet{})
|
err = DB.AutoMigrate(&models.User{}, &models.Sheet{}, &models.Composer{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Failed to migrate database:", err)
|
log.Fatal("Failed to migrate database:", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ go 1.21
|
|||||||
require (
|
require (
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/golang-jwt/jwt/v5 v5.0.0
|
github.com/golang-jwt/jwt/v5 v5.0.0
|
||||||
|
github.com/google/uuid v1.6.0
|
||||||
golang.org/x/crypto v0.9.0
|
golang.org/x/crypto v0.9.0
|
||||||
gorm.io/driver/sqlite v1.5.4
|
gorm.io/driver/sqlite v1.5.4
|
||||||
gorm.io/gorm v1.25.5
|
gorm.io/gorm v1.25.5
|
||||||
@@ -19,7 +20,6 @@ require (
|
|||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
|||||||
96
src/handlers/composers.go
Normal file
96
src/handlers/composers.go
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
"sheetless-server/database"
|
||||||
|
"sheetless-server/models"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AddComposer(c *gin.Context) {
|
||||||
|
var req struct {
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
Bio string `json:"bio"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid, err := GenerateNonexistentComposerUuid()
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Could not generate composer uuid"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
composer := models.Composer{
|
||||||
|
Uuid: *uuid,
|
||||||
|
Name: req.Name,
|
||||||
|
Bio: req.Bio,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := database.DB.Create(&composer).Error; err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create composer"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusCreated, gin.H{
|
||||||
|
"message": "Composer created successfully",
|
||||||
|
"composer": composer,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListComposers(c *gin.Context) {
|
||||||
|
var composers []models.Composer
|
||||||
|
|
||||||
|
if err := database.DB.Find(&composers).Error; err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch composers"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, gin.H{"composers": composers})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetComposer(c *gin.Context) {
|
||||||
|
uuid, err := uuid.Parse(c.Param("uuid"))
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid composer ID"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var composer models.Composer
|
||||||
|
if err := database.DB.First(&composer, uuid).Error; err != nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "Composer not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, composer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateNonexistentComposerUuid() (*uuid.UUID, error) {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
uuid := uuid.New()
|
||||||
|
|
||||||
|
var exists bool
|
||||||
|
err := database.DB.Model(&models.Composer{}).
|
||||||
|
Select("count(*) > 0").
|
||||||
|
Where("uuid = ?", uuid).
|
||||||
|
Find(&exists).
|
||||||
|
Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
return &uuid, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, errors.New("Somehow unable to generate new uuid for sheet.")
|
||||||
|
}
|
||||||
@@ -142,26 +142,23 @@ func ListSheets(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DownloadSheet(c *gin.Context) {
|
func DownloadSheet(c *gin.Context) {
|
||||||
idStr := c.Param("id")
|
uuid, err := uuid.Parse(c.Param("uuid"))
|
||||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid sheet ID"})
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid sheet uuid"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var sheet models.Sheet
|
var sheet models.Sheet
|
||||||
if err := database.DB.First(&sheet, uint(id)).Error; err != nil {
|
if err := database.DB.First(&sheet, uuid).Error; err != nil {
|
||||||
c.JSON(http.StatusNotFound, gin.H{"error": "Sheet not found"})
|
c.JSON(http.StatusNotFound, gin.H{"error": "Sheet not found"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if file exists
|
|
||||||
if _, err := os.Stat(sheet.FilePath); os.IsNotExist(err) {
|
if _, err := os.Stat(sheet.FilePath); os.IsNotExist(err) {
|
||||||
c.JSON(http.StatusNotFound, gin.H{"error": "File not found"})
|
c.JSON(http.StatusNotFound, gin.H{"error": "File not found"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set headers for file download
|
|
||||||
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filepath.Base(sheet.FilePath)))
|
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filepath.Base(sheet.FilePath)))
|
||||||
c.Header("Content-Type", "application/pdf")
|
c.Header("Content-Type", "application/pdf")
|
||||||
c.File(sheet.FilePath)
|
c.File(sheet.FilePath)
|
||||||
|
|||||||
17
src/models/composer.go
Normal file
17
src/models/composer.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Composer struct {
|
||||||
|
Uuid uuid.UUID `json:"uuid" gorm:"type:uuid;primaryKey"`
|
||||||
|
Name string `json:"name" gorm:"not null"`
|
||||||
|
Bio string `json:"bio"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
DeletedAt gorm.DeletedAt `json:"-" gorm:"index"`
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Sheet struct {
|
type Sheet struct {
|
||||||
Uuid uuid.UUID `json:"uuid" gorm:"primaryKey"`
|
Uuid uuid.UUID `json:"uuid" gorm:"type:uuid;primaryKey"`
|
||||||
Title string `json:"title" gorm:"not null"`
|
Title string `json:"title" gorm:"not null"`
|
||||||
Composer string `json:"composer"`
|
Composer string `json:"composer"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
|||||||
@@ -23,7 +23,14 @@ func SetupRoutes(r *gin.Engine) {
|
|||||||
{
|
{
|
||||||
sheets.POST("/upload", handlers.UploadSheet)
|
sheets.POST("/upload", handlers.UploadSheet)
|
||||||
sheets.GET("/list", handlers.ListSheets)
|
sheets.GET("/list", handlers.ListSheets)
|
||||||
sheets.GET("/get/:id", handlers.DownloadSheet)
|
sheets.GET("/get/:uuid", handlers.DownloadSheet)
|
||||||
|
}
|
||||||
|
|
||||||
|
composers := api.Group("/composers")
|
||||||
|
{
|
||||||
|
composers.POST("/add", handlers.AddComposer)
|
||||||
|
composers.GET("/list", handlers.ListComposers)
|
||||||
|
composers.GET("/get/:uuid", handlers.GetComposer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user