diff --git a/cmd/main.go b/cmd/main.go index 3226c87..dbaec28 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -9,6 +9,7 @@ import ( "github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/vault" "github.com/KristianJBorgwarth/dendrite.daemon/core/logging" "github.com/KristianJBorgwarth/dendrite.daemon/core/server" + "github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories" _ "modernc.org/sqlite" ) @@ -16,9 +17,14 @@ func main() { logging.Init() server := server.NewServer() + uow := repositories.NewUnitOfWork(); + linkRepo := repositories.NewLinkRepository() + tagRepo := repositories.NewTagRepository() + noteRepo := repositories.NewNoteRepository() + server.RegisterHandler("vault/init", vault.NewInitializeHandler()) - server.RegisterHandler("note/create", note.NewCreateNoteHandler()) - server.RegisterHandler("note/save", note.NewSaveNoteHandler()) + server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagRepo, noteRepo)) + server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, linkRepo, tagRepo, noteRepo)) 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 a99c319..9def74a 100644 --- a/core/handlers/note/create_note_handler.go +++ b/core/handlers/note/create_note_handler.go @@ -19,11 +19,17 @@ type createNoteCommand struct { } type CreateNoteHandler struct { - uow *repositories.UnitOfWork + uow *repositories.UnitOfWork + tagRepo repositories.ITagRepository + noteRepo repositories.NoteRepository } -func NewCreateNoteHandler() *CreateNoteHandler { - return &CreateNoteHandler{repositories.NewUnitOfWork()} +func NewCreateNoteHandler( + uow *repositories.UnitOfWork, + tagRepo repositories.ITagRepository, + noteRepo repositories.NoteRepository, +) *CreateNoteHandler { + return &CreateNoteHandler{uow, tagRepo, noteRepo} } func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { @@ -47,10 +53,7 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an defer h.uow.Rollback() - tagRepo := repositories.NewTagRepository(dbCtx) - noteRepo := repositories.NewNoteRepository() - - dbTags, err := tagRepo.GetByNames(ctx, template.FrontMatter.Tags) + dbTags, err := h.tagRepo.GetByNames(ctx, dbCtx, template.FrontMatter.Tags) if err != nil { return nil, err } @@ -69,7 +72,7 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an return nil, err } - if err = tagRepo.Insert(ctx, tagModels); err != nil { + if err = h.tagRepo.Insert(ctx, dbCtx, tagModels); err != nil { return nil, err } @@ -77,11 +80,11 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an note := models.CreateNote(notePath, cmd.Title, template.Slug) - if err = noteRepo.Insert(ctx, dbCtx, note); err != nil { + if err = h.noteRepo.Insert(ctx, dbCtx, note); err != nil { return nil, err } - if err = tagRepo.InsertNoteTags(ctx, note.ID(), utils.Select(tagModels, func(t *models.Tag) string { return t.ID() })); err != nil { + if err = h.tagRepo.InsertNoteTags(ctx, dbCtx, note.ID(), utils.Select(tagModels, func(t *models.Tag) string { return t.ID() })); err != nil { return nil, err } diff --git a/core/handlers/note/save_note.go b/core/handlers/note/save_note.go index d1eac64..8b86c2e 100644 --- a/core/handlers/note/save_note.go +++ b/core/handlers/note/save_note.go @@ -16,11 +16,19 @@ type saveNoteCommand struct { } type SaveNoteHandler struct { - uow *repositories.UnitOfWork + uow *repositories.UnitOfWork + linkRepo repositories.ILinkRepository + tagRepo repositories.ITagRepository + noteRepo repositories.NoteRepository } -func NewSaveNoteHandler() *SaveNoteHandler { - return &SaveNoteHandler{repositories.NewUnitOfWork()} +func NewSaveNoteHandler( + uow *repositories.UnitOfWork, + linkRepo repositories.ILinkRepository, + tagRepo repositories.ITagRepository, + noteRepo repositories.NoteRepository, +) *SaveNoteHandler { + return &SaveNoteHandler{uow, linkRepo, tagRepo, noteRepo} } func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { @@ -43,22 +51,19 @@ func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, } defer h.uow.Rollback() - noteRepo := repositories.NewNoteRepository() - linkRepo := repositories.NewLinkRepository(tx) - tagRepo := repositories.NewTagRepository(tx) - note, err := noteRepo.GetBySlug(ctx, tx, file.Slug) + note, err := h.noteRepo.GetBySlug(ctx, tx, file.Slug) if err != nil { slog.Debug("Failed to get note by slug", "slug", file.Slug, "error", err) return nil, err } if note == nil { - if err := h.handleNewNote(ctx, tx, noteRepo, linkRepo, tagRepo, file); err != nil { + if err := h.handleNewNote(ctx, tx, file); err != nil { return nil, err } } else { - if err := h.handleExistingNote(ctx, linkRepo, tagRepo, note, file); err != nil { + if err := h.handleExistingNote(ctx, tx, note, file); err != nil { return nil, err } } @@ -71,28 +76,25 @@ func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, func (h *SaveNoteHandler) handleNewNote( ctx context.Context, - IDbContext persistence.IDbContext, - noteRepo repositories.NoteRepository, - linkRepo repositories.ILinkRepository, - tagRepo repositories.ITagRepository, + 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 := noteRepo.Insert(ctx, IDbContext, note); err != nil { + 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 := linkRepo.Insert(ctx, links); err != nil { + 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 := tagRepo.InsertNoteTags(ctx, note.ID(), file.FrontMatter.Tags); err != nil { + 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 } @@ -100,13 +102,13 @@ func (h *SaveNoteHandler) handleNewNote( return nil } -func (h *SaveNoteHandler) handleExistingNote(ctx context.Context, - linkRepo repositories.ILinkRepository, - tagRepo repositories.ITagRepository, +func (h *SaveNoteHandler) handleExistingNote( + ctx context.Context, + dbCtx persistence.IDbContext, note *models.Note, file *filehandling.File, ) error { - err := h.deleteExistingNoteRelations(ctx, linkRepo, tagRepo, note.ID()) + 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 @@ -114,12 +116,12 @@ func (h *SaveNoteHandler) handleExistingNote(ctx context.Context, links := models.MapToLinkModel(note.ID(), file.ExtractedLinks) - if err = linkRepo.Insert(ctx, links); err != nil { + 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 = tagRepo.InsertNoteTags(ctx, note.ID(), file.FrontMatter.Tags); err != nil { + 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 } @@ -127,11 +129,15 @@ func (h *SaveNoteHandler) handleExistingNote(ctx context.Context, return nil } -func (h *SaveNoteHandler) deleteExistingNoteRelations(ctx context.Context, linkRepo repositories.ILinkRepository, tagRepo repositories.ITagRepository, noteID string) error { - if err := linkRepo.Delete(ctx, noteID); err != 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 := tagRepo.DeleteNoteTags(ctx, noteID); err != nil { + if err := h.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 c75b6f3..5e568ea 100644 --- a/core/services/tag_service.go +++ b/core/services/tag_service.go @@ -1 +1 @@ -package +package services diff --git a/dendrite b/dendrite index c9a2ce5..42a1742 100755 Binary files a/dendrite and b/dendrite differ diff --git a/persistence/repositories/link_repository.go b/persistence/repositories/link_repository.go index 3bc30ff..dc45cbe 100644 --- a/persistence/repositories/link_repository.go +++ b/persistence/repositories/link_repository.go @@ -1,30 +1,28 @@ package repositories import ( - "strings" "context" + "strings" "github.com/KristianJBorgwarth/dendrite.daemon/core/models" "github.com/KristianJBorgwarth/dendrite.daemon/persistence" ) type ILinkRepository interface { - Insert(ctx context.Context, links []*models.Link) error - GetByNoteID(ctx context.Context, fromNoteID string) ([]*models.Link, error) - GetBySlug(ctx context.Context, targetSlug string) ([]*models.Link, error) - Search(ctx context.Context, query string) ([]*models.Link, error) - Delete(ctx context.Context, fromNoteID string) error + Insert(ctx context.Context, dbContext persistence.IDbContext, links []*models.Link) error + GetByNoteID(ctx context.Context, dbContext persistence.IDbContext, fromNoteID string) ([]*models.Link, error) + GetBySlug(ctx context.Context, dbContext persistence.IDbContext, targetSlug string) ([]*models.Link, error) + Search(ctx context.Context, dbContext persistence.IDbContext, query string) ([]*models.Link, error) + Delete(ctx context.Context, dbContext persistence.IDbContext, fromNoteID string) error } -type linkRepository struct { - dbContext persistence.IDbContext +type linkRepository struct{} + +func NewLinkRepository() ILinkRepository { + return &linkRepository{} } -func NewLinkRepository(ctx persistence.IDbContext) ILinkRepository { - return &linkRepository{dbContext: ctx} -} - -func (r *linkRepository) Insert(ctx context.Context, links []*models.Link) error { +func (r *linkRepository) Insert(ctx context.Context, dbContext persistence.IDbContext, links []*models.Link) error { if len(links) == 0 { return nil } @@ -37,14 +35,14 @@ func (r *linkRepository) Insert(ctx context.Context, links []*models.Link) error args = append(args, link.ID(), link.FromNoteID(), link.TargetSlug(), link.Raw(), link.Display(), link.Line(), link.Col()) } - query := "INSERT OR IGNORE INTO link(id, from_note_id, target_slug, raw, display, line, col) VALUES " + strings.Join(placeholders, ",") + query := "INSERT OR IGNORE INTO link(id, from_note_id, target_slug, raw, display, line, col) VALUES " + strings.Join(placeholders, ",") - _, err := r.dbContext.ExecContext(ctx, query, args...) + _, err := dbContext.ExecContext(ctx, query, args...) return err } -func (r *linkRepository) GetByNoteID(ctx context.Context, fromNoteID string) ([]*models.Link, error) { - rows, err := r.dbContext.QueryContext(ctx, "SELECT id, from_note_id, target_slug, raw, display, line, col FROM link WHERE from_note_id = ?", fromNoteID) +func (r *linkRepository) GetByNoteID(ctx context.Context, dbContext persistence.IDbContext, fromNoteID string) ([]*models.Link, error) { + rows, err := dbContext.QueryContext(ctx, "SELECT id, from_note_id, target_slug, raw, display, line, col FROM link WHERE from_note_id = ?", fromNoteID) if err != nil { return nil, err } @@ -63,8 +61,8 @@ func (r *linkRepository) GetByNoteID(ctx context.Context, fromNoteID string) ([] return links, nil } -func (r *linkRepository) GetBySlug(ctx context.Context, targetSlug string) ([]*models.Link, error) { - rows, err := r.dbContext.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM link WHERE target_slug = ?`, targetSlug) +func (r *linkRepository) GetBySlug(ctx context.Context, dbContext persistence.IDbContext, targetSlug string) ([]*models.Link, error) { + rows, err := dbContext.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM link WHERE target_slug = ?`, targetSlug) if err != nil { return nil, err } @@ -83,8 +81,8 @@ func (r *linkRepository) GetBySlug(ctx context.Context, targetSlug string) ([]*m return links, nil } -func (r *linkRepository) Search(ctx context.Context, query string) ([]*models.Link, error) { - rows, err := r.dbContext.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM link WHERE raw LIKE ?`, "%"+query+"%") +func (r *linkRepository) Search(ctx context.Context, dbContext persistence.IDbContext, query string) ([]*models.Link, error) { + rows, err := dbContext.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM link WHERE raw LIKE ?`, "%"+query+"%") if err != nil { return nil, err } @@ -103,7 +101,7 @@ func (r *linkRepository) Search(ctx context.Context, query string) ([]*models.Li return links, nil } -func (r *linkRepository) Delete(ctx context.Context, fromNoteID string) error { - _, err := r.dbContext.ExecContext(ctx, "DELETE FROM link WHERE from_note_id = ?", fromNoteID) +func (r *linkRepository) Delete(ctx context.Context, dbContext persistence.IDbContext, fromNoteID string) error { + _, err := dbContext.ExecContext(ctx, "DELETE FROM link WHERE from_note_id = ?", fromNoteID) return err } diff --git a/persistence/repositories/tag_repository.go b/persistence/repositories/tag_repository.go index ec7ccd9..f170f89 100644 --- a/persistence/repositories/tag_repository.go +++ b/persistence/repositories/tag_repository.go @@ -9,21 +9,19 @@ import ( ) type ITagRepository interface { - Insert(ctx context.Context, tags []*models.Tag) error - InsertNoteTags(ctx context.Context, noteID string, tagIDs []string) error - GetByNames(ctx context.Context, names []string) ([]*models.Tag, error) - DeleteNoteTags(ctx context.Context, noteID string) error + Insert(ctx context.Context, dbCtx persistence.IDbContext, tags []*models.Tag) error + InsertNoteTags(ctx context.Context, dbCtx persistence.IDbContext, noteID string, tagIDs []string) error + GetByNames(ctx context.Context, dbCtx persistence.IDbContext, names []string) ([]*models.Tag, error) + DeleteNoteTags(ctx context.Context, dbCtx persistence.IDbContext, noteID string) error } -type tagRepository struct { - dbContext persistence.IDbContext +type tagRepository struct{} + +func NewTagRepository() ITagRepository { + return &tagRepository{} } -func NewTagRepository(ctx persistence.IDbContext) ITagRepository { - return &tagRepository{dbContext: ctx} -} - -func (r *tagRepository) Insert(ctx context.Context, tags []*models.Tag) error { +func (r *tagRepository) Insert(ctx context.Context, dbCtx persistence.IDbContext, tags []*models.Tag) error { if len(tags) == 0 { return nil } @@ -38,11 +36,11 @@ func (r *tagRepository) Insert(ctx context.Context, tags []*models.Tag) error { query := "INSERT OR IGNORE INTO tag(id, name) VALUES " + strings.Join(placeholders, ",") - _, err := r.dbContext.ExecContext(ctx, query, args...) + _, err := dbCtx.ExecContext(ctx, query, args...) return err } -func (r *tagRepository) InsertNoteTags(ctx context.Context ,noteID string, tagIDs []string) error { +func (r *tagRepository) InsertNoteTags(ctx context.Context, dbCtx persistence.IDbContext, noteID string, tagIDs []string) error { if len(tagIDs) == 0 { return nil } @@ -57,7 +55,7 @@ func (r *tagRepository) InsertNoteTags(ctx context.Context ,noteID string, tagID query := "INSERT OR IGNORE INTO note_tag(note_id, tag_id) VALUES " + strings.Join(placeholders, ",") - _, err := r.dbContext.ExecContext(ctx, query, args...) + _, err := dbCtx.ExecContext(ctx, query, args...) if err != nil { return err } @@ -65,7 +63,7 @@ func (r *tagRepository) InsertNoteTags(ctx context.Context ,noteID string, tagID return nil } -func (r *tagRepository) GetByNames(ctx context.Context, names []string) ([]*models.Tag, error) { +func (r *tagRepository) GetByNames(ctx context.Context, dbCtx persistence.IDbContext, names []string) ([]*models.Tag, error) { if len(names) == 0 { return []*models.Tag{}, nil } @@ -80,7 +78,7 @@ func (r *tagRepository) GetByNames(ctx context.Context, names []string) ([]*mode query := "SELECT id, name FROM tag WHERE name IN (" + strings.Join(placeholders, ",") + ")" - rows, err := r.dbContext.QueryContext(ctx, query, args...) + rows, err := dbCtx.QueryContext(ctx, query, args...) if err != nil { return nil, err } @@ -99,8 +97,8 @@ func (r *tagRepository) GetByNames(ctx context.Context, names []string) ([]*mode return tags, nil } -func (r *tagRepository) DeleteNoteTags(ctx context.Context, noteID string) error { +func (r *tagRepository) DeleteNoteTags(ctx context.Context, dbCtx persistence.IDbContext, noteID string) error { query := "DELETE FROM note_tag WHERE note_id = ?" - _, err := r.dbContext.ExecContext(ctx, query, noteID) + _, err := dbCtx.ExecContext(ctx, query, noteID) return err }