diff --git a/cmd/main.go b/cmd/main.go index 9848439..d2efd75 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,7 +1,6 @@ package main import ( - "database/sql" "log/slog" "os" diff --git a/core/files/doc.go b/core/files/doc.go new file mode 100644 index 0000000..a4727ba --- /dev/null +++ b/core/files/doc.go @@ -0,0 +1,2 @@ +// Package files provides utilities for working with files and directories. +package files diff --git a/core/files/file_handler.go b/core/files/file_handler.go new file mode 100644 index 0000000..3ba059b --- /dev/null +++ b/core/files/file_handler.go @@ -0,0 +1,19 @@ +package files + +import "os" + +func WriteToFile(path string, data []byte) (filePath string, err error) { + if checkIfFileExists(path) { + return path, nil + } + err = os.WriteFile(path, data, 0o644) + if err != nil { + return "", err + } + return path, nil +} + +func checkIfFileExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} diff --git a/core/frontmatter/parser.go b/core/frontmatter/parser.go index 073d394..cf346a7 100644 --- a/core/frontmatter/parser.go +++ b/core/frontmatter/parser.go @@ -16,7 +16,7 @@ type FrontMatter struct { Author string } -func ParseFrontMatter(r io.Reader) (map[string]string, error) { +func parseFrontMatter(r io.Reader) (map[string]string, error) { scanner := bufio.NewScanner(r) frontMatter := make(map[string]string) @@ -41,13 +41,19 @@ func ParseFrontMatter(r io.Reader) (map[string]string, error) { return frontMatter, nil } -func ExtractTags(frontMatter map[string]string) ([]string, error) { +func ExtractTags(file []byte ) ([]string, error) { + r := bytes.NewReader(file) + frontMatter, err := parseFrontMatter(r) + if err != nil { + return nil, err + } tagsStr, ok := frontMatter["tags"] if !ok { - return nil, errors.New("tags not found in front matter") + return nil, nil } + var tags []string - err := json.Unmarshal([]byte(tagsStr), &tags) + err = json.Unmarshal([]byte(tagsStr), &tags) if err != nil { return nil, err } diff --git a/core/handlers/create_note_handler.go b/core/handlers/create_note_handler.go index 841a8ec..c275ecb 100644 --- a/core/handlers/create_note_handler.go +++ b/core/handlers/create_note_handler.go @@ -7,8 +7,8 @@ import ( "encoding/json" "os" + "github.com/KristianJBorgwarth/dendrite.daemon/core/files" "github.com/KristianJBorgwarth/dendrite.daemon/core/frontmatter" - "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" ) @@ -27,26 +27,21 @@ func NewCreateNoteHandler(uow *repositories.UnitOfWork) *CreateNoteHandler { return &CreateNoteHandler{uow: uow} } -func (h CreateNoteHandler) Handle(ctx context.Context, params []byte) (*rpc.Response) { +func (h CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { var cmd createNoteCommand - if err := json.Unmarshal(params, &cmd); err != nil { - return nil, h.ReturnError(err) + if err := json.Unmarshal(raw, &cmd); err != nil { + return nil, err } - data, err := os.ReadFile(cmd.TemplatePath) + data, err := h.getTemplate(cmd.TemplatePath) if err != nil { - return nil, h.ReturnError(err) + return nil, err } - feMatter, err := frontmatter.ParseFrontMatter(bytes.NewReader(data)) + tags, err := frontmatter.ExtractTags(data) if err != nil { - return nil, h.ReturnError(err) - } - - tags, err := frontmatter.ExtractTags(feMatter) - if err != nil { - return nil, h.ReturnError(err) + return nil, err } err = h.uow.Execute(ctx, func(tx *sql.Tx) error { @@ -63,14 +58,20 @@ func (h CreateNoteHandler) Handle(ctx context.Context, params []byte) (*rpc.Resp return nil }) - if err != nil { - return nil, h.ReturnError(err) + return nil, err } - return &rpc.Response{Jsonrpc: "2.0", Result: cmd.Path}, nil + return cmd.Path, nil } -func (h *CreateNoteHandler) ReturnError(err error) *rpc.Error { - return &rpc.Error{Code: -1, Message: err.Error()} +func (h *CreateNoteHandler) getTemplate(templatePath string) ([]byte, error) { + if templatePath == "" { + return nil, nil + } + data, err := os.ReadFile(templatePath) + if err != nil { + return nil, err + } + return data, nil } diff --git a/core/handlers/handler.go b/core/handlers/handler.go index cde1d26..001c62e 100644 --- a/core/handlers/handler.go +++ b/core/handlers/handler.go @@ -3,10 +3,8 @@ package handlers import ( "context" "encoding/json" - - "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" ) type Handler interface { - Handle(ctx context.Context, raw json.RawMessage) (*rpc.Response) + Handle(ctx context.Context, raw json.RawMessage) (any, error) } diff --git a/core/handlers/initialize_handler.go b/core/handlers/initialize_handler.go index a84003d..6e33f12 100644 --- a/core/handlers/initialize_handler.go +++ b/core/handlers/initialize_handler.go @@ -3,36 +3,26 @@ package handlers import ( "context" "encoding/json" - - "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" "github.com/KristianJBorgwarth/dendrite.daemon/persistence" ) type initializeCommand struct { - VaultPath string `json:"vaultPath"` + VaultPath string `json:"vaultPath"` } type InitializeHandler struct{} -func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, *rpc.Error) { +func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { var params initializeCommand if err := json.Unmarshal(raw, ¶ms); err != nil { - return nil, &rpc.Error{ - Code: -32602, - Message: "invalid params: " + err.Error(), - } + return nil, err } - err := persistence.InitializeIndex(params.VaultPath) if err != nil { - return nil, &rpc.Error{ - Code: -1, - Message: "failed to initialize index: " + err.Error(), - } + return nil, err } return nil, nil } - diff --git a/core/server/server.go b/core/server/server.go index 6aed220..646036a 100644 --- a/core/server/server.go +++ b/core/server/server.go @@ -4,7 +4,6 @@ package server import ( "bufio" "context" - "database/sql" "encoding/json" "fmt" "io" @@ -14,7 +13,6 @@ import ( ) type Server struct { - Db *sql.DB handlers map[string]handlers.Handler } @@ -24,10 +22,6 @@ func NewServer() *Server { } } -func (s *Server) InitDatabase(db *sql.DB) { - s.Db = db -} - func (s *Server) Register(method string, handler handlers.Handler) { s.handlers[method] = handler } @@ -58,24 +52,42 @@ func (s *Server) handle(w io.Writer, req rpc.Request) { handler, ok := s.handlers[req.Method] if !ok { - s.write(w, rpc.Response{ - Jsonrpc: "2.0", - ID: req.ID, - Error: &rpc.Error{Code: -32601, Message: "method not found"}, + s.respond(w, req.ID, nil, &rpc.Error{ + Code: -32601, + Message: "method not found", }) - return -} + return + } - result := handler.Handle(ctx, req.Params) + result, err := handler.Handle(ctx, req.Params) + if err != nil { + s.respond(w, req.ID, nil, &rpc.Error{ + Code: -32000, + Message: err.Error(), + }) + return + } if req.ID == nil { return } - s.write(w, *result) + s.respond(w, req.ID, result, nil) +} + +func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) { + resultJSON, _ := json.Marshal(result) + resp := rpc.Response{ + Jsonrpc: "2.0", + ID: id, + Result: resultJSON, + Error: err, + } + + s.write(w, resp) } func (s *Server) write(w io.Writer, resp rpc.Response) { data, _ := json.Marshal(resp) - fmt.Fprintln(w, string(data)) + fmt.Fprintln(w, string(data)) } diff --git a/core/template/templater.go b/core/template/templater.go new file mode 100644 index 0000000..40576a7 --- /dev/null +++ b/core/template/templater.go @@ -0,0 +1,17 @@ +package template + +import ( + "os" +) + + +func GenerateTemplate(templatePath string) ([]byte, error) { + if templatePath == "" { + return nil, nil + } + data, err := os.ReadFile(templatePath) + if err != nil { + return nil, err + } + return data, nil +} diff --git a/test/test_integration/create_note_handler_test.go b/test/test_integration/create_note_handler_test.go index 97f3348..e210a42 100644 --- a/test/test_integration/create_note_handler_test.go +++ b/test/test_integration/create_note_handler_test.go @@ -10,7 +10,7 @@ import ( func TestCreateNoteHandlerOnSucess(t *testing.T) { // Arrange - uow := repositories.NewUnitOfWork(Fixture.Db) + uow := repositories.NewUnitOfWork(Fixture.DB) handler := handlers.NewCreateNoteHandler(uow) @@ -30,18 +30,14 @@ func TestCreateNoteHandlerOnSucess(t *testing.T) { request := CreateTestRequest("createNote", 1, requestParamsBytes) // Act - response := handler.Handle(Fixture.TestContext, request.Params) + response, err := handler.Handle(Fixture.TestContext, request.Params) // Assert - if response.Error != nil { - t.Fatalf("expected no error, got: %v", response.Error) + if err != nil { + t.Fatalf("handler returned an error: %v", err) } - if response.Result == nil { - t.Fatal("expected result, got nil") - } - - if *response.ID != 1 { - t.Fatal("expected non-empty ID in response result") + if response != nil { + t.Fatalf("expected response to be nil, got: %v", response) } } diff --git a/test/test_integration/main_test.go b/test/test_integration/main_test.go index 14668b8..363ed8f 100644 --- a/test/test_integration/main_test.go +++ b/test/test_integration/main_test.go @@ -5,44 +5,48 @@ import ( "database/sql" "encoding/json" "os" + "path/filepath" "testing" "github.com/KristianJBorgwarth/dendrite.daemon/core/rpc" "github.com/KristianJBorgwarth/dendrite.daemon/persistence" + _ "modernc.org/sqlite" ) -type TestFixture struct { - Db *sql.DB - DbPath string +type DBFixture struct { + DB *sql.DB + DBPath string TestContext context.Context } -func NewTestFixture() (*TestFixture, error) { - dbPath := os.TempDir() + "/dendrite_test_vault" - db, err := sql.Open("sqlite", dbPath) - if err != nil { - return nil, err - } +func NewDBFixture() *DBFixture { + vaultPath := os.TempDir() - return &TestFixture{ - Db: db, - DbPath: dbPath, - TestContext: context.Background(), - }, nil -} - -var Fixture, err = NewTestFixture() - -func TestMain(m *testing.M) { - - err := persistence.InitializeIndex(Fixture.DbPath) + err := persistence.InitializeIndex(vaultPath) if err != nil { panic(err) } + dbPath := filepath.Join(os.TempDir(), ".index", "index.db") + + db, err := sql.Open("sqlite", dbPath) + if err != nil { + panic(err) + } + + return &DBFixture{ + DB: db, + DBPath: dbPath, + TestContext: context.Background(), + } +} + +var Fixture = NewDBFixture() + +func TestMain(m *testing.M) { code := m.Run() - os.RemoveAll(Fixture.DbPath) + os.RemoveAll(Fixture.DBPath) os.Exit(code) } @@ -55,5 +59,3 @@ func CreateTestRequest(method string, ID int, params json.RawMessage) *rpc.Reque Params: params, } } - -