feat(cfe): add cfe on save and rebuild (#45)
This commit is contained in:
parent
87536b474a
commit
2f94782d33
8 changed files with 98 additions and 27 deletions
|
|
@ -26,18 +26,19 @@ func main() {
|
||||||
linkRepo := repositories.NewLinkRepository(persistence.NewReadContext())
|
linkRepo := repositories.NewLinkRepository(persistence.NewReadContext())
|
||||||
tagRepo := repositories.NewTagRepository(persistence.NewReadContext())
|
tagRepo := repositories.NewTagRepository(persistence.NewReadContext())
|
||||||
noteRepo := repositories.NewNoteRepository(persistence.NewReadContext())
|
noteRepo := repositories.NewNoteRepository(persistence.NewReadContext())
|
||||||
|
cfeRepo := repositories.NewCfeRepository(persistence.NewReadContext())
|
||||||
|
|
||||||
tagService := services.NewTagService(tagRepo)
|
tagService := services.NewTagService(tagRepo)
|
||||||
linkService := services.NewLinkService(linkRepo)
|
linkService := services.NewLinkService(linkRepo)
|
||||||
noteService := services.NewNoteService(tagRepo, linkRepo, noteRepo)
|
noteService := services.NewNoteService(tagRepo, linkRepo, noteRepo, cfeRepo)
|
||||||
cfeSvc := services.NewCfeService(repositories.NewCfeRepository(persistence.NewReadContext()))
|
cfeSvc := services.NewCfeService(cfeRepo)
|
||||||
idxr := services.NewIndexRebuilder(uow, noteRepo, linkRepo, tagRepo, indexRepo )
|
idxr := services.NewIndexRebuilder(uow, noteRepo, linkRepo, tagRepo, indexRepo, cfeRepo)
|
||||||
|
|
||||||
server.RegisterHandler("vault/init", vault.NewInitializeHandler(idxr, noteService))
|
server.RegisterHandler("vault/init", vault.NewInitializeHandler(idxr, noteService))
|
||||||
server.RegisterHandler("vault/rebuild", vault.NewRebuildIndexHandler(idxr))
|
server.RegisterHandler("vault/rebuild", vault.NewRebuildIndexHandler(idxr))
|
||||||
|
|
||||||
server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagService, noteRepo, cfeSvc))
|
server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagService, noteRepo, cfeSvc))
|
||||||
server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, noteRepo, tagService, noteService, linkService))
|
server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, noteRepo, tagService, noteService, linkService, cfeSvc))
|
||||||
server.RegisterHandler("note/delete", note.NewDeleteNoteHandler(uow, tagService, noteService))
|
server.RegisterHandler("note/delete", note.NewDeleteNoteHandler(uow, tagService, noteService))
|
||||||
server.RegisterHandler("note/goto", note.NewGotoNoteHandler(noteRepo))
|
server.RegisterHandler("note/goto", note.NewGotoNoteHandler(noteRepo))
|
||||||
server.RegisterHandler("note/backlinks", note.NewGetBackLinksHandler(linkRepo, noteRepo))
|
server.RegisterHandler("note/backlinks", note.NewGetBackLinksHandler(linkRepo, noteRepo))
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ type SaveNoteHandler struct {
|
||||||
tagService services.ITagService
|
tagService services.ITagService
|
||||||
noteService services.INoteService
|
noteService services.INoteService
|
||||||
linkService services.ILinkService
|
linkService services.ILinkService
|
||||||
|
cfeSvc services.ICfeService
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSaveNoteHandler(
|
func NewSaveNoteHandler(
|
||||||
|
|
@ -28,8 +29,9 @@ func NewSaveNoteHandler(
|
||||||
ts services.ITagService,
|
ts services.ITagService,
|
||||||
ns services.INoteService,
|
ns services.INoteService,
|
||||||
ls services.ILinkService,
|
ls services.ILinkService,
|
||||||
|
cfs services.ICfeService,
|
||||||
) *SaveNoteHandler {
|
) *SaveNoteHandler {
|
||||||
return &SaveNoteHandler{uow, nr, ts, ns, ls}
|
return &SaveNoteHandler{uow, nr, ts, ns, ls, cfs}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) {
|
func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) {
|
||||||
|
|
@ -84,6 +86,10 @@ func (h *SaveNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (any,
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = h.cfeSvc.AddCfe(ctx, tx, note.ID(), file.FrontMatter.Custom); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := h.uow.Commit(); err != nil {
|
if err := h.uow.Commit(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import filehandling "github.com/KristianJBorgwarth/dendrite.daemon/core/file_handling"
|
import (
|
||||||
|
"errors"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
filehandling "github.com/KristianJBorgwarth/dendrite.daemon/core/file_handling"
|
||||||
|
)
|
||||||
|
|
||||||
func MapToLinkModel(noteID string, extractedLinks []*filehandling.ExtractedLink) []*Link {
|
func MapToLinkModel(noteID string, extractedLinks []*filehandling.ExtractedLink) []*Link {
|
||||||
var links []*Link
|
var links []*Link
|
||||||
|
|
@ -10,20 +15,23 @@ func MapToLinkModel(noteID string, extractedLinks []*filehandling.ExtractedLink)
|
||||||
return links
|
return links
|
||||||
}
|
}
|
||||||
|
|
||||||
func MapToCfe(noteID string, extractedCfe map[string]any) []*CustomFronMatter {
|
func MapToCfe(noteID string, extractedCfe map[string]any) ([]*CustomFronMatter, error) {
|
||||||
var cfe []*CustomFronMatter
|
var cfe []*CustomFronMatter
|
||||||
for key, value := range extractedCfe {
|
for key, value := range extractedCfe {
|
||||||
if valueStr, ok := value.(string); ok {
|
if valueStr, ok := value.(string); ok {
|
||||||
cfe = append(cfe, NewCustomFrontMatter(noteID, key, valueStr))
|
cfe = append(cfe, NewCustomFrontMatter(noteID, key, valueStr))
|
||||||
continue
|
continue
|
||||||
} else if valueArr, ok := value.([]string); ok {
|
} else if valueArr, ok := value.([]any); ok {
|
||||||
for _, v := range valueArr {
|
for _, v := range valueArr {
|
||||||
cfe = append(cfe, NewCustomFrontMatter(noteID, key, v))
|
if s, ok := v.(string); ok {
|
||||||
|
cfe = append(cfe, NewCustomFrontMatter(noteID, key, s))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
cfe = append(cfe, NewCustomFrontMatter(noteID, key, ""))
|
slog.Warn("Unsupported CFE value type, skipping", "key", key, "value", value)
|
||||||
|
return nil, errors.New("unsupported CFE value type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cfe
|
return cfe, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ func (s *cfeService) AddCfe(
|
||||||
if len(cfe) == 0 {
|
if len(cfe) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
cfeModels := models.MapToCfe(noteID, cfe)
|
cfeModels, err := models.MapToCfe(noteID, cfe)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return s.cfeRepo.InsertRange(ctx, dbCtx, cfeModels)
|
return s.cfeRepo.InsertRange(ctx, dbCtx, cfeModels)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,14 @@ import (
|
||||||
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/store"
|
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type index struct {
|
||||||
|
notes []*models.Note
|
||||||
|
links []*models.Link
|
||||||
|
cfe []*models.CustomFronMatter
|
||||||
|
tags []*models.Tag
|
||||||
|
noteTags []*models.NoteTag
|
||||||
|
}
|
||||||
|
|
||||||
type IIndexRebuilder interface {
|
type IIndexRebuilder interface {
|
||||||
RebuildIndex(ctx context.Context, vaultRoot string) error
|
RebuildIndex(ctx context.Context, vaultRoot string) error
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +33,7 @@ type indexRebuilder struct {
|
||||||
linkRepo repositories.ILinkRepository
|
linkRepo repositories.ILinkRepository
|
||||||
tagRepo repositories.ITagRepository
|
tagRepo repositories.ITagRepository
|
||||||
indexRepo repositories.IIndexRepository
|
indexRepo repositories.IIndexRepository
|
||||||
|
cfeRepo repositories.ICfeRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIndexRebuilder(
|
func NewIndexRebuilder(
|
||||||
|
|
@ -33,6 +42,7 @@ func NewIndexRebuilder(
|
||||||
linkRepo repositories.ILinkRepository,
|
linkRepo repositories.ILinkRepository,
|
||||||
tagRepo repositories.ITagRepository,
|
tagRepo repositories.ITagRepository,
|
||||||
indexRepo repositories.IIndexRepository,
|
indexRepo repositories.IIndexRepository,
|
||||||
|
cfeRepo repositories.ICfeRepository,
|
||||||
) *indexRebuilder {
|
) *indexRebuilder {
|
||||||
return &indexRebuilder{
|
return &indexRebuilder{
|
||||||
uow: uow,
|
uow: uow,
|
||||||
|
|
@ -40,6 +50,7 @@ func NewIndexRebuilder(
|
||||||
linkRepo: linkRepo,
|
linkRepo: linkRepo,
|
||||||
tagRepo: tagRepo,
|
tagRepo: tagRepo,
|
||||||
indexRepo: indexRepo,
|
indexRepo: indexRepo,
|
||||||
|
cfeRepo: cfeRepo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,13 +65,16 @@ func (r *indexRebuilder) RebuildIndex(ctx context.Context, vaultRoot string) err
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
notes, links, tags, noteTags := r.buildDBModels(files)
|
index, err := r.buildDBModels(files)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if err = r.indexRepo.WipeIndex(ctx, dbctx); err != nil {
|
if err = r.indexRepo.WipeIndex(ctx, dbctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = r.buildIndex(ctx, dbctx, notes, links, tags, noteTags); err != nil {
|
if err = r.buildIndex(ctx, dbctx, index); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -74,24 +88,25 @@ func (r *indexRebuilder) RebuildIndex(ctx context.Context, vaultRoot string) err
|
||||||
func (r *indexRebuilder) buildIndex(
|
func (r *indexRebuilder) buildIndex(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
dbctx persistence.IDbContext,
|
dbctx persistence.IDbContext,
|
||||||
notes []*models.Note,
|
index *index,
|
||||||
links []*models.Link,
|
|
||||||
tags []*models.Tag,
|
|
||||||
noteTags []*models.NoteTag,
|
|
||||||
) error {
|
) error {
|
||||||
if err := r.noteRepo.InsertRange(ctx, dbctx, notes); err != nil {
|
if err := r.noteRepo.InsertRange(ctx, dbctx, index.notes); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.linkRepo.InsertRange(ctx, dbctx, links); err != nil {
|
if err := r.linkRepo.InsertRange(ctx, dbctx, index.links); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.tagRepo.InsertRange(ctx, dbctx, tags); err != nil {
|
if err := r.tagRepo.InsertRange(ctx, dbctx, index.tags); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.tagRepo.InsertNoteTags(ctx, dbctx, noteTags); err != nil {
|
if err := r.tagRepo.InsertNoteTags(ctx, dbctx, index.noteTags); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.cfeRepo.InsertRange(ctx, dbctx, index.cfe); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,9 +161,10 @@ func (r *indexRebuilder) IsValidDirectory(path string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *indexRebuilder) buildDBModels(files []*filehandling.File) ([]*models.Note, []*models.Link, []*models.Tag, []*models.NoteTag) {
|
func (r *indexRebuilder) buildDBModels(files []*filehandling.File) (*index, error) {
|
||||||
var notes []*models.Note
|
var notes []*models.Note
|
||||||
var links []*models.Link
|
var links []*models.Link
|
||||||
|
var cfe []*models.CustomFronMatter
|
||||||
tagMap := make(map[string]*models.Tag)
|
tagMap := make(map[string]*models.Tag)
|
||||||
var noteTags []*models.NoteTag
|
var noteTags []*models.NoteTag
|
||||||
|
|
||||||
|
|
@ -160,6 +176,12 @@ func (r *indexRebuilder) buildDBModels(files []*filehandling.File) ([]*models.No
|
||||||
}
|
}
|
||||||
noteTags = append(noteTags, models.CreateNoteTags(note.ID(), file.FrontMatter.Tags)...)
|
noteTags = append(noteTags, models.CreateNoteTags(note.ID(), file.FrontMatter.Tags)...)
|
||||||
links = append(links, models.MapToLinkModel(note.ID(), file.ExtractedLinks)...)
|
links = append(links, models.MapToLinkModel(note.ID(), file.ExtractedLinks)...)
|
||||||
|
|
||||||
|
mappedCfe, err := models.MapToCfe(note.ID(), file.FrontMatter.Custom)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfe = append(cfe, mappedCfe...)
|
||||||
}
|
}
|
||||||
|
|
||||||
tags := make([]*models.Tag, 0, len(tagMap))
|
tags := make([]*models.Tag, 0, len(tagMap))
|
||||||
|
|
@ -167,5 +189,11 @@ func (r *indexRebuilder) buildDBModels(files []*filehandling.File) ([]*models.No
|
||||||
tags = append(tags, tag)
|
tags = append(tags, tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
return notes, links, tags, noteTags
|
return &index{
|
||||||
|
notes: notes,
|
||||||
|
links: links,
|
||||||
|
tags: tags,
|
||||||
|
noteTags: noteTags,
|
||||||
|
cfe: cfe,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,16 @@ type noteService struct {
|
||||||
tagRepo repositories.ITagRepository
|
tagRepo repositories.ITagRepository
|
||||||
linkRepo repositories.ILinkRepository
|
linkRepo repositories.ILinkRepository
|
||||||
noteRepo repositories.INoteRepository
|
noteRepo repositories.INoteRepository
|
||||||
|
cfeRepo repositories.ICfeRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNoteService(
|
func NewNoteService(
|
||||||
tagRepo repositories.ITagRepository,
|
tagRepo repositories.ITagRepository,
|
||||||
linkRepo repositories.ILinkRepository,
|
linkRepo repositories.ILinkRepository,
|
||||||
noteRepo repositories.INoteRepository,
|
noteRepo repositories.INoteRepository,
|
||||||
|
cfeRepo repositories.ICfeRepository,
|
||||||
) INoteService {
|
) INoteService {
|
||||||
return ¬eService{tagRepo, linkRepo, noteRepo}
|
return ¬eService{tagRepo, linkRepo, noteRepo, cfeRepo}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *noteService) CreateNote(ctx context.Context, dbCtx persistence.IDbContext, path, title, slug string) (*models.Note, error) {
|
func (s *noteService) CreateNote(ctx context.Context, dbCtx persistence.IDbContext, path, title, slug string) (*models.Note, error) {
|
||||||
|
|
@ -56,6 +58,10 @@ func (s *noteService) DeleteNoteMetaData(ctx context.Context, dbCtx persistence.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := s.cfeRepo.Delete(ctx, dbCtx, noteID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
type ICfeRepository interface {
|
type ICfeRepository interface {
|
||||||
InsertRange(ctx context.Context, dbContext persistence.IDbContext, cfe []*models.CustomFronMatter) error
|
InsertRange(ctx context.Context, dbContext persistence.IDbContext, cfe []*models.CustomFronMatter) error
|
||||||
|
Delete(ctx context.Context, dbContext persistence.IDbContext, noteID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type cfeRepository struct {
|
type cfeRepository struct {
|
||||||
|
|
@ -26,7 +27,7 @@ func (r *cfeRepository) InsertRange(
|
||||||
) error {
|
) error {
|
||||||
statement, err := dbCtx.Prepare(
|
statement, err := dbCtx.Prepare(
|
||||||
`INSERT INTO custom_frontmatter (note_id, key, value)
|
`INSERT INTO custom_frontmatter (note_id, key, value)
|
||||||
VALUES (?, ?, ?) ON CONFLICT DO NOTHING;`,)
|
VALUES (?, ?, ?) ON CONFLICT DO NOTHING;`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -39,3 +40,20 @@ func (r *cfeRepository) InsertRange(
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *cfeRepository) Delete(
|
||||||
|
ctx context.Context,
|
||||||
|
dbCtx persistence.IDbContext,
|
||||||
|
noteID string,
|
||||||
|
) error {
|
||||||
|
statement, err := dbCtx.Prepare(`DELETE FROM custom_frontmatter WHERE note_id = ?;`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := statement.ExecContext(ctx, noteID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@ func (r *indexRepository) WipeIndex(ctx context.Context, dbContext persistence.I
|
||||||
cmd := `DELETE FROM note;
|
cmd := `DELETE FROM note;
|
||||||
DELETE FROM tag;
|
DELETE FROM tag;
|
||||||
DELETE FROM note_tag;
|
DELETE FROM note_tag;
|
||||||
DELETE FROM link;`
|
DELETE FROM link;
|
||||||
|
DELETE FROM custom_frontmatter;`
|
||||||
|
|
||||||
_, err := dbContext.ExecContext(ctx, cmd)
|
_, err := dbContext.ExecContext(ctx, cmd)
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue