61 lines
2.1 KiB
Go
61 lines
2.1 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"encoding/hex"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
"golang.org/x/crypto/blake2b"
|
|
|
|
"git.jmbit.de/jmb/scanfile/server/internal/sqlc"
|
|
"git.jmbit.de/jmb/scanfile/server/internal/store"
|
|
)
|
|
|
|
// CreateFile() creates the filesystem object and the DB entry for a file
|
|
func CreateFile(ctx context.Context, name string, fileBytes []byte) (sqlc.File, error) {
|
|
queries := sqlc.New(pool)
|
|
file := sqlc.File{
|
|
Name: name,
|
|
}
|
|
var err error
|
|
|
|
bl2hash := blake2b.Sum256(fileBytes)
|
|
slog.Debug("calculated Blake2b hash", "file-name", name, "file-bl2", hex.EncodeToString(bl2hash[:]), "file-size", len(fileBytes))
|
|
mime, _ := store.GetBytesFileType(fileBytes[:262])
|
|
|
|
file, err = queries.CreateFile(ctx, sqlc.CreateFileParams{
|
|
Name: name,
|
|
Mimetype: mime,
|
|
Size: int64(len(fileBytes)),
|
|
Blake2: bl2hash[:],
|
|
})
|
|
if err == pgx.ErrNoRows {
|
|
file, err := queries.GetFileByBlake2(ctx, bl2hash[:])
|
|
if err != nil {
|
|
slog.Error("Error saving file to database", "error", err, "file-name", name)
|
|
return file, err
|
|
}
|
|
slog.Debug("File already exists", "file-uuid", file.ID.String(), "file-name", file.Name, "file-bl2", hex.EncodeToString(file.Blake2), "file-size", file.Size, "file-mime", file.Mimetype, "file-description", file.Description.String)
|
|
return file, nil
|
|
}
|
|
if err != nil {
|
|
slog.Error("Error saving file to database", "error", err, "file-name", name)
|
|
err = nil
|
|
} else {
|
|
slog.Debug("New file created", "file-uuid", file.ID.String(), "file-name", file.Name, "file-bl2", hex.EncodeToString(file.Blake2), "file-size", file.Size, "file-mime", file.Mimetype, "file-description", file.Description.String)
|
|
}
|
|
|
|
//Using UUIDs instead of the file hash to make switching storage backends easier
|
|
_, err = store.SaveFile(file.ID.String(), fileBytes)
|
|
if err != nil {
|
|
slog.Error("Error saving file to disk", "error", err, "file-uuid", file.ID.String())
|
|
errdel := queries.DeleteFile(ctx, file.ID)
|
|
if errdel != nil {
|
|
slog.Error("Error deleting file from database", "error", errdel, "file-uuid", file.ID.String())
|
|
}
|
|
return file, err
|
|
}
|
|
|
|
return file, nil
|
|
}
|