migrate files + upload meta data

This commit is contained in:
m
2026-07-12 09:33:04 +02:00
parent 1d35bea1c5
commit 1f3bee120d
8 changed files with 235 additions and 15 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ func main() {
} }
defer database.Close() defer database.Close()
if err := db.RunMigrations(database, migrationsPath); err != nil { if err := db.RunMigrations(migrationsPath); err != nil {
log.Fatalf("Failed to run migrations: %v", err) log.Fatalf("Failed to run migrations: %v", err)
} }
+142
View File
@@ -0,0 +1,142 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: files.sql
package db
import (
"context"
)
const createFile = `-- name: CreateFile :one
INSERT INTO files (id, name, mime_type, size, storage_key, checksum, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
RETURNING id, name, mime_type, size, storage_key, checksum, ocr_text, created_at, updated_at
`
type CreateFileParams struct {
ID string `json:"id"`
Name string `json:"name"`
MimeType string `json:"mime_type"`
Size int64 `json:"size"`
StorageKey string `json:"storage_key"`
Checksum string `json:"checksum"`
}
func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, error) {
row := q.db.QueryRowContext(ctx, createFile,
arg.ID,
arg.Name,
arg.MimeType,
arg.Size,
arg.StorageKey,
arg.Checksum,
)
var i File
err := row.Scan(
&i.ID,
&i.Name,
&i.MimeType,
&i.Size,
&i.StorageKey,
&i.Checksum,
&i.OcrText,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const deleteFile = `-- name: DeleteFile :exec
DELETE FROM files
WHERE id = ?
`
func (q *Queries) DeleteFile(ctx context.Context, id string) error {
_, err := q.db.ExecContext(ctx, deleteFile, id)
return err
}
const getFile = `-- name: GetFile :one
SELECT id, name, mime_type, size, storage_key, checksum, ocr_text, created_at, updated_at FROM files
WHERE id = ? LIMIT 1
`
func (q *Queries) GetFile(ctx context.Context, id string) (File, error) {
row := q.db.QueryRowContext(ctx, getFile, id)
var i File
err := row.Scan(
&i.ID,
&i.Name,
&i.MimeType,
&i.Size,
&i.StorageKey,
&i.Checksum,
&i.OcrText,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listFiles = `-- name: ListFiles :many
SELECT id, name, mime_type, size, storage_key, checksum, ocr_text, created_at, updated_at FROM files
ORDER BY created_at DESC
`
func (q *Queries) ListFiles(ctx context.Context) ([]File, error) {
rows, err := q.db.QueryContext(ctx, listFiles)
if err != nil {
return nil, err
}
defer rows.Close()
var items []File
for rows.Next() {
var i File
if err := rows.Scan(
&i.ID,
&i.Name,
&i.MimeType,
&i.Size,
&i.StorageKey,
&i.Checksum,
&i.OcrText,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateFile = `-- name: UpdateFile :exec
UPDATE files
SET name = ?, mime_type = ?, ocr_text = ?, updated_at = CURRENT_TIMESTAMP
WHERE id = ?
`
type UpdateFileParams struct {
Name string `json:"name"`
MimeType string `json:"mime_type"`
OcrText string `json:"ocr_text"`
ID string `json:"id"`
}
func (q *Queries) UpdateFile(ctx context.Context, arg UpdateFileParams) error {
_, err := q.db.ExecContext(ctx, updateFile,
arg.Name,
arg.MimeType,
arg.OcrText,
arg.ID,
)
return err
}
+8 -3
View File
@@ -1,7 +1,6 @@
package db package db
import ( import (
"database/sql"
"fmt" "fmt"
"log" "log"
@@ -10,13 +9,19 @@ import (
"github.com/golang-migrate/migrate/v4/source/file" "github.com/golang-migrate/migrate/v4/source/file"
) )
func RunMigrations(database *sql.DB, migrationsURL string) error { func RunMigrations(migrationsURL string) error {
migDB, err := Connect()
if err != nil {
return fmt.Errorf("open migration db: %w", err)
}
defer migDB.Close()
sourceDriver, err := (&file.File{}).Open(migrationsURL) sourceDriver, err := (&file.File{}).Open(migrationsURL)
if err != nil { if err != nil {
return fmt.Errorf("open migrations source: %w", err) return fmt.Errorf("open migrations source: %w", err)
} }
dbDriver, err := sqlite.WithInstance(database, &sqlite.Config{}) dbDriver, err := sqlite.WithInstance(migDB, &sqlite.Config{})
if err != nil { if err != nil {
return fmt.Errorf("create sqlite driver: %w", err) return fmt.Errorf("create sqlite driver: %w", err)
} }
@@ -0,0 +1 @@
DROP TABLE IF EXISTS files;
@@ -0,0 +1,11 @@
CREATE TABLE files (
id TEXT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
mime_type TEXT NOT NULL DEFAULT '',
size INTEGER NOT NULL DEFAULT 0,
storage_key TEXT NOT NULL,
checksum TEXT NOT NULL DEFAULT '',
ocr_text TEXT NOT NULL DEFAULT '',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
+16
View File
@@ -3,3 +3,19 @@
// sqlc v1.31.1 // sqlc v1.31.1
package db package db
import (
"time"
)
type File struct {
ID string `json:"id"`
Name string `json:"name"`
MimeType string `json:"mime_type"`
Size int64 `json:"size"`
StorageKey string `json:"storage_key"`
Checksum string `json:"checksum"`
OcrText string `json:"ocr_text"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
+21
View File
@@ -0,0 +1,21 @@
-- name: GetFile :one
SELECT * FROM files
WHERE id = ? LIMIT 1;
-- name: ListFiles :many
SELECT * FROM files
ORDER BY created_at DESC;
-- name: CreateFile :one
INSERT INTO files (id, name, mime_type, size, storage_key, checksum, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
RETURNING *;
-- name: UpdateFile :exec
UPDATE files
SET name = ?, mime_type = ?, ocr_text = ?, updated_at = CURRENT_TIMESTAMP
WHERE id = ?;
-- name: DeleteFile :exec
DELETE FROM files
WHERE id = ?;
+35 -11
View File
@@ -1,6 +1,10 @@
package handlers package handlers
import ( import (
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"net/http" "net/http"
"os" "os"
"path" "path"
@@ -8,6 +12,7 @@ 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"
) )
@@ -215,19 +220,38 @@ func (h *Handlers) UploadFile(c *gin.Context) {
} }
checksum := service.CreateSHA256Hash(fileByte) checksum := service.CreateSHA256Hash(fileByte)
// TODO: re-enable once files table + query are added
// createFileParams := db.CreateFileParams{ ctx := context.Background()
// Name: file.Filename,
// StorageKey: dst, id := make([]byte, 16)
// Checksum: string(checksum[:]), rand.Read(id)
// }
// dbFile, err := h.queries.CreateFile(ctx, createFileParams) createFileParams := db.CreateFileParams{
_ = checksum ID: hex.EncodeToString(id),
Name: file.Filename,
Size: file.Size,
StorageKey: dst,
Checksum: hex.EncodeToString(checksum),
}
dbFile, err := h.queries.CreateFile(ctx, createFileParams)
if err != nil {
fmt.Println(err)
c.JSON(http.StatusInternalServerError, gin.H{
"error": gin.H{
"code": "DB_ERROR",
"message": "Failed to save file metadata",
},
})
return
}
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"error": gin.H{ "data": gin.H{
"code": "SUCCESS", "id": dbFile.ID,
"message": "Uploaded", "name": dbFile.Name,
}, },
}) })