create file into db

This commit is contained in:
m
2026-07-12 09:15:06 +02:00
parent ab3957040d
commit c2e0c9fce4
9 changed files with 122 additions and 37 deletions
+13 -12
View File
@@ -21,24 +21,25 @@ func main() {
} }
defer database.Close() defer database.Close()
_ = database // will be passed to handlers once queries are implemented queries := db.New(database)
h := handlers.New(queries)
r := gin.Default() r := gin.Default()
r.GET("/api/v1/health", handlers.Health) r.GET("/api/v1/health", h.Health)
r.GET("/api/v1/files", handlers.ListFiles) r.GET("/api/v1/files", h.ListFiles)
r.GET("/api/v1/file/:id", handlers.ListFile) r.GET("/api/v1/file/:id", h.ListFile)
r.POST("/api/v1/files/upload", handlers.UploadFile) r.POST("/api/v1/files/upload", h.UploadFile)
r.GET("/api/v1/files/:id", handlers.GetFile) r.GET("/api/v1/files/:id", h.GetFile)
r.DELETE("/api/v1/files/:id", handlers.DeleteFile) r.DELETE("/api/v1/files/:id", h.DeleteFile)
r.GET("/api/v1/files/search", handlers.SearchFiles) r.GET("/api/v1/files/search", h.SearchFiles)
r.POST("/api/v1/files/:id/tags", handlers.AddTags) r.POST("/api/v1/files/:id/tags", h.AddTags)
r.GET("/api/v1/files/:id/tags", handlers.GetTags) r.GET("/api/v1/files/:id/tags", h.GetTags)
r.POST("/api/v1/ocr/jobs", handlers.CreateOcrJob) r.POST("/api/v1/ocr/jobs", h.CreateOcrJob)
r.GET("/api/v1/ocr/jobs/:id", handlers.GetOcrJobStatus) r.GET("/api/v1/ocr/jobs/:id", h.GetOcrJobStatus)
log.Printf("Server starting on port %s", port) log.Printf("Server starting on port %s", port)
if err := r.Run(":" + port); err != nil { if err := r.Run(":" + port); err != nil {
+3 -4
View File
@@ -7,7 +7,6 @@ package db
import ( import (
"context" "context"
"database/sql"
) )
const createFile = `-- name: CreateFile :one const createFile = `-- name: CreateFile :one
@@ -20,9 +19,9 @@ RETURNING id, name, storage_key, checksum, created_at, updated_at, deleted_at
` `
type CreateFileParams struct { type CreateFileParams struct {
Name string `json:"name"` Name string `json:"name"`
StorageKey string `json:"storage_key"` StorageKey string `json:"storage_key"`
Checksum sql.NullString `json:"checksum"` Checksum string `json:"checksum"`
} }
func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, error) { func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, error) {
+1 -1
View File
@@ -2,7 +2,7 @@ CREATE TABLE files (
id TEXT PRIMARY KEY, id TEXT PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
storage_key TEXT NOT NULL, storage_key TEXT NOT NULL,
checksum TEXT, checksum TEXT NOT NULL,
created_at INTEGER NOT NULL, created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL, updated_at INTEGER NOT NULL,
deleted_at INTEGER deleted_at INTEGER
+7 -7
View File
@@ -9,13 +9,13 @@ import (
) )
type File struct { type File struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
StorageKey string `json:"storage_key"` StorageKey string `json:"storage_key"`
Checksum sql.NullString `json:"checksum"` Checksum string `json:"checksum"`
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"` UpdatedAt int64 `json:"updated_at"`
DeletedAt sql.NullInt64 `json:"deleted_at"` DeletedAt sql.NullInt64 `json:"deleted_at"`
} }
type FileTag struct { type FileTag struct {
+62 -10
View File
@@ -1,6 +1,8 @@
package handlers package handlers
import ( import (
"context"
"fmt"
"net/http" "net/http"
"os" "os"
"path" "path"
@@ -8,11 +10,12 @@ import (
"strconv" "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/vaultdrop/backend/internal/db"
"github.com/vaultdrop/backend/internal/service" "github.com/vaultdrop/backend/internal/service"
) )
// retourne qui est delete qui est updated et created // retourne qui est delete qui est updated et created
func SyncFiles(c *gin.Context) { func (h *Handlers) SyncFiles(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{ c.JSON(http.StatusNotImplemented, gin.H{
"error": gin.H{ "error": gin.H{
"code": "NOT_IMPLEMENTED", "code": "NOT_IMPLEMENTED",
@@ -21,7 +24,7 @@ func SyncFiles(c *gin.Context) {
}) })
} }
func ListFiles(c *gin.Context) { func (h *Handlers) ListFiles(c *gin.Context) {
dirs, err := os.ReadDir("./uploads/") dirs, err := os.ReadDir("./uploads/")
@@ -79,7 +82,7 @@ func ListFiles(c *gin.Context) {
}) })
} }
func ListFile(c *gin.Context) { func (h *Handlers) ListFile(c *gin.Context) {
id := c.Param("id") id := c.Param("id")
@@ -144,7 +147,7 @@ func ListFile(c *gin.Context) {
}) })
} }
func GetFile(c *gin.Context) { func (h *Handlers) GetFile(c *gin.Context) {
exp, _ := strconv.ParseInt(c.Query("expires"), 10, 64) exp, _ := strconv.ParseInt(c.Query("expires"), 10, 64)
@@ -167,7 +170,9 @@ func GetFile(c *gin.Context) {
} }
func UploadFile(c *gin.Context) { func (h *Handlers) UploadFile(c *gin.Context) {
ctx := context.Background()
file, err := c.FormFile("file") file, err := c.FormFile("file")
@@ -182,7 +187,53 @@ func UploadFile(c *gin.Context) {
dst := filepath.Join("./uploads/", filepath.Base(file.Filename)) dst := filepath.Join("./uploads/", filepath.Base(file.Filename))
c.SaveUploadedFile(file, dst) err = c.SaveUploadedFile(file, dst)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": gin.H{
"code": "ERROR",
"message": "Uploaded",
},
})
return
}
fileByte, err := os.ReadFile(dst)
if err != nil {
// fmt.Println("error reading file")
c.JSON(http.StatusInternalServerError, gin.H{
"error": gin.H{
"code": "ERROR",
"message": "Error reading file",
},
})
return
}
checksum := service.CreateSHA256Hash(fileByte)
// save generate meta data
createFileParams := db.CreateFileParams{
Name: file.Filename,
StorageKey: dst,
Checksum: string(checksum[:]),
}
dbFile, err := h.queries.CreateFile(ctx, createFileParams)
if err != nil {
fmt.Println(err)
}
fmt.Println(dbFile.Checksum)
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"error": gin.H{ "error": gin.H{
@@ -190,9 +241,10 @@ func UploadFile(c *gin.Context) {
"message": "Uploaded", "message": "Uploaded",
}, },
}) })
} }
func DeleteFile(c *gin.Context) { func (h *Handlers) DeleteFile(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{ c.JSON(http.StatusNotImplemented, gin.H{
"error": gin.H{ "error": gin.H{
"code": "NOT_IMPLEMENTED", "code": "NOT_IMPLEMENTED",
@@ -201,7 +253,7 @@ func DeleteFile(c *gin.Context) {
}) })
} }
func SearchFiles(c *gin.Context) { func (h *Handlers) SearchFiles(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"data": []interface{}{}, "data": []interface{}{},
"meta": gin.H{ "meta": gin.H{
@@ -211,7 +263,7 @@ func SearchFiles(c *gin.Context) {
}) })
} }
func AddTags(c *gin.Context) { func (h *Handlers) AddTags(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{ c.JSON(http.StatusNotImplemented, gin.H{
"error": gin.H{ "error": gin.H{
"code": "NOT_IMPLEMENTED", "code": "NOT_IMPLEMENTED",
@@ -220,7 +272,7 @@ func AddTags(c *gin.Context) {
}) })
} }
func GetTags(c *gin.Context) { func (h *Handlers) GetTags(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"data": []interface{}{}, "data": []interface{}{},
}) })
+11
View File
@@ -0,0 +1,11 @@
package handlers
import "github.com/vaultdrop/backend/internal/db"
type Handlers struct {
queries *db.Queries
}
func New(queries *db.Queries) *Handlers {
return &Handlers{queries: queries}
}
+1 -1
View File
@@ -6,7 +6,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func Health(c *gin.Context) { func (h *Handlers) Health(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"data": gin.H{ "data": gin.H{
"status": "healthy", "status": "healthy",
+2 -2
View File
@@ -6,7 +6,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func CreateOcrJob(c *gin.Context) { func (h *Handlers) CreateOcrJob(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{ c.JSON(http.StatusNotImplemented, gin.H{
"error": gin.H{ "error": gin.H{
"code": "NOT_IMPLEMENTED", "code": "NOT_IMPLEMENTED",
@@ -15,7 +15,7 @@ func CreateOcrJob(c *gin.Context) {
}) })
} }
func GetOcrJobStatus(c *gin.Context) { func (h *Handlers) GetOcrJobStatus(c *gin.Context) {
c.JSON(http.StatusNotFound, gin.H{ c.JSON(http.StatusNotFound, gin.H{
"error": gin.H{ "error": gin.H{
"code": "JOB_NOT_FOUND", "code": "JOB_NOT_FOUND",
+22
View File
@@ -0,0 +1,22 @@
package service
import (
"crypto/sha256"
"crypto/subtle"
)
func CreateSHA256Hash(data []byte) []byte {
hasher := sha256.New()
hasher.Write(data)
return hasher.Sum(nil)
}
func CompareHash(x, y []byte) bool {
if len(x) != len(y) {
return false
}
return subtle.ConstantTimeCompare(x, y) == 1
}