ref(handlers): uow passsed to method
This commit is contained in:
parent
ca34b0dc62
commit
2537140053
7 changed files with 44 additions and 40 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue