diff --git a/cmd/main.go b/cmd/main.go index 0305054..ab743c5 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -23,10 +23,12 @@ func main() { tagRepo := repositories.NewTagRepository() noteRepo := repositories.NewNoteRepository() tagService := services.NewTagService(tagRepo) + linkService := services.NewLinkService(linkRepo) + noteService := services.NewNoteService(tagRepo, linkRepo, noteRepo) server.RegisterHandler("vault/init", vault.NewInitializeHandler()) server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagService, noteRepo)) - server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, linkRepo, tagRepo, noteRepo)) + server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, noteRepo, tagService, noteService, linkService)) server.RegisterHandler("completion/link", completion.NewCompleteLinkHandler()) if err := server.Run(os.Stdin, os.Stdout); err != nil { diff --git a/core/handlers/note/create_note_handler.go b/core/handlers/note/create_note_handler.go index 026a89a..beb2f07 100644 --- a/core/handlers/note/create_note_handler.go +++ b/core/handlers/note/create_note_handler.go @@ -21,13 +21,13 @@ type createNoteCommand struct { type CreateNoteHandler struct { uow *repositories.UnitOfWork tagService services.ITagService - noteRepo repositories.NoteRepository + noteRepo repositories.INoteRepository } func NewCreateNoteHandler( uow *repositories.UnitOfWork, tagRepo services.ITagService, - noteRepo repositories.NoteRepository, + noteRepo repositories.INoteRepository, ) *CreateNoteHandler { return &CreateNoteHandler{uow, tagRepo, noteRepo} } diff --git a/core/handlers/note/save_note.go b/core/handlers/note/save_note.go index 8b86c2e..871ab60 100644 --- a/core/handlers/note/save_note.go +++ b/core/handlers/note/save_note.go @@ -6,8 +6,7 @@ import ( "log/slog" filehandling "github.com/KristianJBorgwarth/dendrite.daemon/core/file_handling" - "github.com/KristianJBorgwarth/dendrite.daemon/core/models" - "github.com/KristianJBorgwarth/dendrite.daemon/persistence" + "github.com/KristianJBorgwarth/dendrite.daemon/core/services" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" ) @@ -16,19 +15,21 @@ type saveNoteCommand struct { } type SaveNoteHandler struct { - uow *repositories.UnitOfWork - linkRepo repositories.ILinkRepository - tagRepo repositories.ITagRepository - noteRepo repositories.NoteRepository + uow *repositories.UnitOfWork + noteRepo repositories.INoteRepository + tagService services.ITagService + noteService services.INoteService + linkService services.ILinkService } func NewSaveNoteHandler( uow *repositories.UnitOfWork, - linkRepo repositories.ILinkRepository, - tagRepo repositories.ITagRepository, - noteRepo repositories.NoteRepository, + nr repositories.INoteRepository, + ts services.ITagService, + ns services.INoteService, + ls services.ILinkService, ) *SaveNoteHandler { - return &SaveNoteHandler{uow, linkRepo, tagRepo, noteRepo} + return &SaveNoteHandler{uow, nr, ts, ns, ls} } func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { @@ -49,7 +50,6 @@ func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, if err != nil { return nil, err } - defer h.uow.Rollback() note, err := h.noteRepo.GetBySlug(ctx, tx, file.Slug) @@ -59,90 +59,36 @@ func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, } if note == nil { - if err := h.handleNewNote(ctx, tx, file); err != nil { + note, err = h.noteService.CreateNote(ctx, tx, file.Path, file.Title, file.Slug) + if err != nil { + slog.Debug("Failed to save new note", "slug", file.Slug, "error", err) return nil, err } } else { - if err := h.handleExistingNote(ctx, tx, note, file); err != nil { + if err = h.noteService.DeleteNoteMetaData(ctx, tx, note.ID()); err != nil { + slog.Debug("Failed to delete existing note metadata", "noteID", note.ID(), "error", err) return nil, err } } + tagModels, err := h.tagService.CreateTags(ctx, tx, file.FrontMatter.Tags) + if err != nil { + slog.Debug("Failed to create tags", "tags", file.FrontMatter.Tags, "error", err) + return nil, err + } + + if err = h.tagService.CreateNoteTags(ctx, tx, note.ID(), tagModels); err != nil { + slog.Debug("Failed to create note tags", "noteID", note.ID(), "tags", file.FrontMatter.Tags, "error", err) + return nil, err + } + + if err = h.linkService.CreateLinks(ctx, tx, note.ID(), file.ExtractedLinks); err != nil { + slog.Debug("Failed to create links", "noteID", note.ID(), "links", file.ExtractedLinks, "error", err) + return nil, err + } + if err := h.uow.Commit(); err != nil { return nil, err } return nil, nil } - -func (h *SaveNoteHandler) handleNewNote( - ctx context.Context, - dbCtx persistence.IDbContext, - file *filehandling.File, -) error { - note := models.CreateNote(file.Path, file.Title, file.Slug) - slog.Debug("EXTRACTED FILE", "path", file.Path, "title", file.Title, "slug", file.Slug, "links", file.ExtractedLinks, "tags", file.FrontMatter.Tags) - - if err := h.noteRepo.Insert(ctx, dbCtx, note); err != nil { - slog.Debug("Failed to insert new note", "noteID", note.ID(), "error", err) - return err - } - - links := models.MapToLinkModel(note.ID(), file.ExtractedLinks) - - if err := h.linkRepo.Insert(ctx, dbCtx, links); err != nil { - slog.Debug("Failed to insert links for new note", "noteID", note.ID(), "error", err) - return err - } - - if err := h.tagRepo.InsertNoteTags(ctx, dbCtx, note.ID(), file.FrontMatter.Tags); err != nil { - slog.Debug("Failed to insert tags for new note", "noteID", note.ID(), "error", err) - return err - } - - return nil -} - -func (h *SaveNoteHandler) handleExistingNote( - ctx context.Context, - dbCtx persistence.IDbContext, - note *models.Note, - file *filehandling.File, -) error { - err := h.deleteExistingNoteRelations(ctx, dbCtx, note.ID()) - if err != nil { - slog.Debug("Failed to delete existing note relations", "noteID", note.ID(), "error", err) - return err - } - - links := models.MapToLinkModel(note.ID(), file.ExtractedLinks) - - if err = h.linkRepo.Insert(ctx, dbCtx, links); err != nil { - slog.Debug("Failed to insert links for existing note", "noteID", note.ID(), "error", err) - return err - } - - if err = h.tagRepo.InsertNoteTags(ctx, dbCtx, note.ID(), file.FrontMatter.Tags); err != nil { - slog.Debug("Failed to insert tags for existing note", "noteID", note.ID(), "error", err) - return err - } - - return nil -} - -func (h *SaveNoteHandler) deleteExistingNoteRelations( - ctx context.Context, - dbCtx persistence.IDbContext, - noteID string, -) error { - if err := h.linkRepo.Delete(ctx, dbCtx, noteID); err != nil { - return err - } - if err := h.tagRepo.DeleteNoteTags(ctx, dbCtx, noteID); err != nil { - return err - } - return nil -} - -func (h *SaveNoteHandler) handleTags(ctx context.Context, tagRepo repositories.ITagRepository, noteID string, tags []string) error { - panic("not implemented") -} diff --git a/core/services/link_service.go b/core/services/link_service.go new file mode 100644 index 0000000..31ce992 --- /dev/null +++ b/core/services/link_service.go @@ -0,0 +1,34 @@ +package services + +import ( + "context" + "log/slog" + + filehandling "github.com/KristianJBorgwarth/dendrite.daemon/core/file_handling" + "github.com/KristianJBorgwarth/dendrite.daemon/core/models" + "github.com/KristianJBorgwarth/dendrite.daemon/persistence" + "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" +) + +type ILinkService interface { + CreateLinks(ctx context.Context, dbCtx persistence.IDbContext, noteID string, links []*filehandling.ExtractedLink) error +} + +type linkService struct { + linkRepo repositories.ILinkRepository +} + +func NewLinkService(linkRepo repositories.ILinkRepository) ILinkService { + return &linkService{linkRepo} +} + +func (s *linkService) CreateLinks(ctx context.Context, dbCtx persistence.IDbContext, noteID string, links []*filehandling.ExtractedLink) error { + if len(links) == 0 { + return nil + } + + linkModels := models.MapToLinkModel(noteID, links) + slog.Debug("Creating links", "noteID", noteID, "links", linkModels) + return s.linkRepo.Insert(ctx, dbCtx, linkModels) +} + diff --git a/core/services/note_service.go b/core/services/note_service.go new file mode 100644 index 0000000..ae5dd99 --- /dev/null +++ b/core/services/note_service.go @@ -0,0 +1,49 @@ +package services + +import ( + "context" + + "github.com/KristianJBorgwarth/dendrite.daemon/core/models" + "github.com/KristianJBorgwarth/dendrite.daemon/persistence" + "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" +) + +type INoteService interface { + CreateNote(ctx context.Context, dbCtx persistence.IDbContext, path, title, slug string) (*models.Note, error) + DeleteNoteMetaData(ctx context.Context, dbCtx persistence.IDbContext, noteID string) error +} + +type noteService struct { + tagRepo repositories.ITagRepository + linkRepo repositories.ILinkRepository + noteRepo repositories.INoteRepository +} + +func NewNoteService( + tagRepo repositories.ITagRepository, + linkRepo repositories.ILinkRepository, + noteRepo repositories.INoteRepository, +) INoteService { + return ¬eService{tagRepo, linkRepo, noteRepo} +} + +func (s *noteService) CreateNote(ctx context.Context, dbCtx persistence.IDbContext, path, title, slug string) (*models.Note, error) { + note:= models.CreateNote(path, title, slug) + if err := s.noteRepo.Insert(ctx, dbCtx, note); err != nil { + return nil, err + } + + return note, nil +} + +func (s *noteService) DeleteNoteMetaData(ctx context.Context, dbCtx persistence.IDbContext, noteID string) error { + if err := s.linkRepo.Delete(ctx, dbCtx, noteID); err != nil { + return err + } + + if err := s.tagRepo.DeleteNoteTags(ctx, dbCtx, noteID); err != nil { + return err + } + + return nil +} diff --git a/core/services/tag_service.go b/core/services/tag_service.go index bb5076e..2d9602a 100644 --- a/core/services/tag_service.go +++ b/core/services/tag_service.go @@ -2,6 +2,7 @@ package services import ( "context" + "log/slog" "github.com/KristianJBorgwarth/dendrite.daemon/core/models" "github.com/KristianJBorgwarth/dendrite.daemon/core/utils" @@ -18,7 +19,7 @@ type tagService struct { tagRepo repositories.ITagRepository } -func NewTagService(tagRepo repositories.ITagRepository) *tagService { +func NewTagService(tagRepo repositories.ITagRepository) ITagService { return &tagService{tagRepo} } @@ -28,6 +29,8 @@ func (s *tagService) CreateTags(ctx context.Context, dbCtx persistence.IDbContex return nil, err } + slog.Debug("Existing tags", "names", names, "existingTags", existingTags) + newTags := utils.Filter(names, func(name string) bool { for _, tag := range existingTags { if tag.Name() == name { @@ -43,6 +46,8 @@ func (s *tagService) CreateTags(ctx context.Context, dbCtx persistence.IDbContex return nil, err } + slog.Debug("Created new tags", "newTags", newTagModels) + tags := append(existingTags, newTagModels...) return tags, nil diff --git a/dendrite b/dendrite index 0138ab9..fbe9e89 100755 Binary files a/dendrite and b/dendrite differ diff --git a/persistence/repositories/note_repository.go b/persistence/repositories/note_repository.go index c04edd9..1ec7dcd 100644 --- a/persistence/repositories/note_repository.go +++ b/persistence/repositories/note_repository.go @@ -9,14 +9,14 @@ import ( "github.com/KristianJBorgwarth/dendrite.daemon/persistence" ) -type NoteRepository interface { +type INoteRepository interface { Insert(ctx context.Context, dbContext persistence.IDbContext, note *models.Note) error GetBySlug(ctx context.Context, dbContext persistence.IDbContext, slug string) (*models.Note, error) } type noteRepository struct{} -func NewNoteRepository() NoteRepository { +func NewNoteRepository() INoteRepository { return ¬eRepository{} }