create file into db
This commit is contained in:
+13
-12
@@ -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 {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const createFile = `-- name: CreateFile :one
|
const createFile = `-- name: CreateFile :one
|
||||||
@@ -22,7 +21,7 @@ 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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ 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"`
|
||||||
|
|||||||
@@ -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{}{},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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}
|
||||||
|
}
|
||||||
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user