ref(handlers): uow passsed to method

This commit is contained in:
Kristian Borgwarth 2026-04-03 21:03:36 +02:00
parent ca34b0dc62
commit 2537140053
7 changed files with 44 additions and 40 deletions

View file

@ -12,7 +12,7 @@ import (
func main() { func main() {
server := server.NewServer() server := server.NewServer()
server.Register("initialize", handlers.InitializeHandler{}) server.RegisterHandler("initialize", handlers.NewInitializeHandler())
if err := server.Run(os.Stdin, os.Stdout); err != nil { if err := server.Run(os.Stdin, os.Stdout); err != nil {
slog.Error("server error", "error", err) slog.Error("server error", "error", err)

View file

@ -18,15 +18,13 @@ type createNoteCommand struct {
Vars map[string]string `json:"vars"` Vars map[string]string `json:"vars"`
} }
type CreateNoteHandler struct { type CreateNoteHandler struct{}
uow *repositories.UnitOfWork
func NewCreateNoteHandler() *CreateNoteHandler {
return &CreateNoteHandler{}
} }
func NewCreateNoteHandler(uow *repositories.UnitOfWork) *CreateNoteHandler { func (h *CreateNoteHandler) Handle(ctx context.Context, uow *repositories.UnitOfWork, raw json.RawMessage) (any, error) {
return &CreateNoteHandler{uow: uow}
}
func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) {
var cmd createNoteCommand var cmd createNoteCommand
if err := json.Unmarshal(raw, &cmd); err != nil { if err := json.Unmarshal(raw, &cmd); err != nil {
@ -45,12 +43,12 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
return nil, err return nil, err
} }
tx, err := h.uow.Begin() tx, err := uow.Begin()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer h.uow.Rollback() defer uow.Rollback()
tagRepo := repositories.NewTagRepository(tx) tagRepo := repositories.NewTagRepository(tx)
noteRepo := repositories.NewNoteRepository(tx) noteRepo := repositories.NewNoteRepository(tx)
@ -74,9 +72,9 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
return nil, err return nil, err
} }
h.uow.FileStore.Stage(cmd.Path, data) uow.FileStore.Stage(cmd.Path, data)
if err = h.uow.Commit(); err != nil { if err = uow.Commit(); err != nil {
return nil, err return nil, err
} }

View file

@ -12,6 +12,10 @@ type initializeCommand struct {
type InitializeHandler struct{} type InitializeHandler struct{}
func NewInitializeHandler() *InitializeHandler {
return &InitializeHandler{}
}
func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) {
var params initializeCommand var params initializeCommand
@ -19,7 +23,7 @@ func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any
return nil, err return nil, err
} }
err := persistence.InitializeIndex(params.VaultPath) _, err := persistence.InitializeIndex(params.VaultPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -4,6 +4,7 @@ package server
import ( import (
"bufio" "bufio"
"context" "context"
"database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -13,6 +14,7 @@ import (
) )
type Server struct { type Server struct {
db *sql.DB
handlers map[string]handlers.Handler handlers map[string]handlers.Handler
} }
@ -22,7 +24,7 @@ func NewServer() *Server {
} }
} }
func (s *Server) Register(method string, handler handlers.Handler) { func (s *Server) RegisterHandler(method string, handler handlers.Handler) {
s.handlers[method] = handler s.handlers[method] = handler
} }
@ -73,6 +75,9 @@ func (s *Server) handle(w io.Writer, req rpc.Request) {
s.respond(w, req.ID, result, nil) s.respond(w, req.ID, result, nil)
} }
func (s *Server) initalize(){
}
func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) { func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) {
resultJSON, _ := json.Marshal(result) resultJSON, _ := json.Marshal(result)
resp := rpc.Response{ resp := rpc.Response{

View file

@ -12,12 +12,12 @@ import (
//go:embed migrations/*.sql //go:embed migrations/*.sql
var migrationsFS embed.FS var migrationsFS embed.FS
func InitializeIndex(vaultPath string) error { func InitializeIndex(vaultPath string) (*sql.DB, error) {
indexDir := filepath.Join(vaultPath, ".index") indexDir := filepath.Join(vaultPath, ".index")
if err := os.MkdirAll(indexDir, 0755); err != nil { if err := os.MkdirAll(indexDir, 0755); err != nil {
slog.Error("failed to create index directory", "error", err) slog.Error("failed to create index directory", "error", err)
return err return nil, err
} }
dbPath := filepath.Join(indexDir, "index.db") dbPath := filepath.Join(indexDir, "index.db")
@ -25,17 +25,16 @@ func InitializeIndex(vaultPath string) error {
db, err := sql.Open("sqlite", dbPath) db, err := sql.Open("sqlite", dbPath)
if err != nil { if err != nil {
slog.Error("failed to open database", "error", err) slog.Error("failed to open database", "error", err)
return err return nil, err
} }
defer db.Close()
if err := applyMigrations(db); err != nil { if err := applyMigrations(db); err != nil {
slog.Error("failed to apply migrations", "error", err) slog.Error("failed to apply migrations", "error", err)
return err return nil, err
} }
return nil return db, nil
} }
func applyMigrations(db *sql.DB) error { func applyMigrations(db *sql.DB) error {

View file

@ -12,14 +12,11 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func newCreateNoteHandler() *handlers.CreateNoteHandler {
uow := repositories.NewUnitOfWork(Fixture.DB)
return handlers.NewCreateNoteHandler(uow)
}
func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T) { func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T) {
// Arrange // Arrange
handler := newCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB)
notePath := filepath.Join(t.TempDir(), "my-note.md") notePath := filepath.Join(t.TempDir(), "my-note.md")
params, _ := json.Marshal(map[string]any{ params, _ := json.Marshal(map[string]any{
"title": "My Note", "title": "My Note",
@ -27,7 +24,7 @@ func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T
}) })
// Act // Act
result, err := handler.Handle(Fixture.TestContext, params) result, err := handler.Handle(Fixture.TestContext, uow, params)
// Assert // Assert
require.NoError(t, err) require.NoError(t, err)
@ -43,7 +40,8 @@ func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T
func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t *testing.T) { func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t *testing.T) {
// Arrange // Arrange
handler := newCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB)
dir := t.TempDir() dir := t.TempDir()
templatePath := filepath.Join(dir, "template.md") templatePath := filepath.Join(dir, "template.md")
@ -57,7 +55,7 @@ func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t
}) })
// Act // Act
result, err := handler.Handle(Fixture.TestContext, params) result, err := handler.Handle(Fixture.TestContext, uow, params)
// Assert // Assert
require.NoError(t, err) require.NoError(t, err)
@ -86,17 +84,20 @@ func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t
func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) { func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) {
// Arrange // Arrange
dir := t.TempDir() dir := t.TempDir()
handler := handlers.NewCreateNoteHandler()
uowInit := repositories.NewUnitOfWork(Fixture.DB)
secondUow := repositories.NewUnitOfWork(Fixture.DB)
path1 := filepath.Join(dir, "dup-note.md") path1 := filepath.Join(dir, "dup-note.md")
params1, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path1}) params1, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path1})
_, err := newCreateNoteHandler().Handle(Fixture.TestContext, params1) _, err := handler.Handle(Fixture.TestContext, uowInit, params1)
require.NoError(t, err) require.NoError(t, err)
path2 := filepath.Join(dir, "dup-note-moved.md") path2 := filepath.Join(dir, "dup-note-moved.md")
params2, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path2}) params2, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path2})
// Act // Act
_, err = newCreateNoteHandler().Handle(Fixture.TestContext, params2) _, err = handler.Handle(Fixture.TestContext, secondUow, params2)
// Assert // Assert
require.NoError(t, err) require.NoError(t, err)
@ -112,10 +113,11 @@ func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) {
func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) { func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) {
// Arrange // Arrange
handler := newCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB)
// Act // Act
_, err := handler.Handle(Fixture.TestContext, json.RawMessage(`{invalid json}`)) _, err := handler.Handle(Fixture.TestContext, uow, json.RawMessage(`{invalid json}`))
// Assert // Assert
assert.Error(t, err) assert.Error(t, err)
@ -123,7 +125,8 @@ func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) {
func TestCreateNoteHandler_NonExistentTemplatePath_ReturnsError(t *testing.T) { func TestCreateNoteHandler_NonExistentTemplatePath_ReturnsError(t *testing.T) {
// Arrange // Arrange
handler := newCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB)
params, _ := json.Marshal(map[string]any{ params, _ := json.Marshal(map[string]any{
"title": "Ghost Note", "title": "Ghost Note",
"path": filepath.Join(t.TempDir(), "ghost.md"), "path": filepath.Join(t.TempDir(), "ghost.md"),
@ -131,7 +134,7 @@ func TestCreateNoteHandler_NonExistentTemplatePath_ReturnsError(t *testing.T) {
}) })
// Act // Act
_, err := handler.Handle(Fixture.TestContext, params) _, err := handler.Handle(Fixture.TestContext, uow, params)
// Assert // Assert
assert.Error(t, err) assert.Error(t, err)

View file

@ -22,18 +22,13 @@ type DBFixture struct {
func NewDBFixture() *DBFixture { func NewDBFixture() *DBFixture {
vaultPath := os.TempDir() vaultPath := os.TempDir()
err := persistence.InitializeIndex(vaultPath) db, err := persistence.InitializeIndex(vaultPath)
if err != nil { if err != nil {
panic(err) panic(err)
} }
dbPath := filepath.Join(os.TempDir(), ".index", "index.db") dbPath := filepath.Join(os.TempDir(), ".index", "index.db")
db, err := sql.Open("sqlite", dbPath)
if err != nil {
panic(err)
}
return &DBFixture{ return &DBFixture{
DB: db, DB: db,
DBPath: dbPath, DBPath: dbPath,