diff --git a/cmd/main.go b/cmd/main.go index f33074e..3d2e16a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -20,16 +20,18 @@ func main() { server := server.NewServer() uow := repositories.NewUnitOfWork(); - indexRepo := repositories.NewIndexRepository() + + indexRepo := repositories.NewIndexRepository(*persistence.NewReadContext()) linkRepo := repositories.NewLinkRepository(*persistence.NewReadContext()) tagRepo := repositories.NewTagRepository() noteRepo := repositories.NewNoteRepository(*persistence.NewReadContext()) + tagService := services.NewTagService(tagRepo) linkService := services.NewLinkService(linkRepo) noteService := services.NewNoteService(tagRepo, linkRepo, noteRepo) idxr := services.NewIndexRebuilder(uow, noteRepo, linkRepo, tagRepo, indexRepo ) - server.RegisterHandler("vault/init", vault.NewInitializeHandler(idxr)) + server.RegisterHandler("vault/init", vault.NewInitializeHandler(idxr, noteService)) server.RegisterHandler("note/create", note.NewCreateNoteHandler(uow, tagService, noteRepo)) server.RegisterHandler("note/save", note.NewSaveNoteHandler(uow, noteRepo, tagService, noteService, linkService)) server.RegisterHandler("note/goto", note.NewGotoNoteHandler(noteRepo)) diff --git a/core/handlers/vault/initialize_handler.go b/core/handlers/vault/initialize_handler.go index 2c345ad..ac75b4e 100644 --- a/core/handlers/vault/initialize_handler.go +++ b/core/handlers/vault/initialize_handler.go @@ -3,6 +3,7 @@ package vault import ( "context" "encoding/json" + "log/slog" "github.com/KristianJBorgwarth/dendrite.daemon/core/services" "github.com/KristianJBorgwarth/dendrite.daemon/persistence" @@ -17,10 +18,11 @@ type initializeCommand struct { type InitializeHandler struct { idxRebuilder services.IIndexRebuilder + noteService services.INoteService } -func NewInitializeHandler(idxR services.IIndexRebuilder) *InitializeHandler { - return &InitializeHandler{idxRebuilder: idxR} +func NewInitializeHandler(idxR services.IIndexRebuilder, nsv services.INoteService) *InitializeHandler { + return &InitializeHandler{idxRebuilder: idxR, noteService: nsv} } func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { @@ -37,7 +39,18 @@ func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any return nil, err } - if err = h.idxRebuilder.RebuildIndex(ctx, cmd.VaultPath); err != nil { + noteCount, err := h.noteService.GetNoteCount(ctx) + if err != nil { + return nil, err + } + + if noteCount > 0 { + slog.Debug("Vault already initialized, skipping index rebuild") + return nil, nil + } + + err = h.idxRebuilder.RebuildIndex(ctx, cmd.VaultPath) + if err != nil { return nil, err } diff --git a/core/services/index_rebuilder.go b/core/services/index_rebuilder.go index 564cf18..8d24c25 100644 --- a/core/services/index_rebuilder.go +++ b/core/services/index_rebuilder.go @@ -34,39 +34,36 @@ func NewIndexRebuilder( indexRepo repositories.IIndexRepository, ) *indexRebuilder { return &indexRebuilder{ - uow: uow, - noteRepo: noteRepo, - linkRepo: linkRepo, - tagRepo: tagRepo, + uow: uow, + noteRepo: noteRepo, + linkRepo: linkRepo, + tagRepo: tagRepo, indexRepo: indexRepo, } } func (r *indexRebuilder) RebuildIndex(ctx context.Context, vaultRoot string) error { - files, err := r.readFiles(vaultRoot) - if err != nil { - slog.Debug("Failed to read files from vault", "vaultRoot", vaultRoot, "error", err) - return err - } - - slog.Debug("Successfully read files from vault", "vaultRoot", vaultRoot, "fileCount", len(files)) - - notes, links, tags, noteTags := r.buildDBModels(files) - dbctx, err := r.uow.Begin() if err != nil { return err } + files, err := r.readFiles(vaultRoot) + if err != nil { + return err + } + + notes, links, tags, noteTags := r.buildDBModels(files) + if err = r.indexRepo.WipeIndex(ctx, dbctx); err != nil { - r.uow.Rollback() - slog.Debug("Failed to wipe index, rolling back transaction", "error", err) return err } if err = r.buildIndex(ctx, dbctx, notes, links, tags, noteTags); err != nil { - r.uow.Rollback() - slog.Debug("Failed to build index, rolling back transaction", "error", err) + return err + } + + if err = r.uow.Commit(); err != nil { return err } @@ -110,7 +107,7 @@ func (r *indexRebuilder) readFiles(vault string) ([]*filehandling.File, error) { slog.Debug("Processing file during index rebuild", "path", path) if d.IsDir() { - if !r.shouldIndexDirectory(path) { + if !r.IsValidDirectory(path) { slog.Debug("Skipping directory during index rebuild", "path", path) return filepath.SkipDir } @@ -138,7 +135,7 @@ func (r *indexRebuilder) readFiles(vault string) ([]*filehandling.File, error) { return files, nil } -func (r *indexRebuilder) shouldIndexDirectory(path string) bool { +func (r *indexRebuilder) IsValidDirectory(path string) bool { ignoredDirs := []string{".git", ".templates", "temp", "issues"} for part := range strings.SplitSeq(path, string(filepath.Separator)) { if slices.Contains(ignoredDirs, part) { diff --git a/core/services/note_service.go b/core/services/note_service.go index 654876e..b2e42d4 100644 --- a/core/services/note_service.go +++ b/core/services/note_service.go @@ -12,6 +12,7 @@ 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 UpdateNote(ctx context.Context, dbCtx persistence.IDbContext, noteID, path, title, slug string) error + GetNoteCount(ctx context.Context) (int, error) } type noteService struct { @@ -55,3 +56,7 @@ func (s *noteService) DeleteNoteMetaData(ctx context.Context, dbCtx persistence. return nil } + +func (s *noteService) GetNoteCount(ctx context.Context) (int, error) { + return s.noteRepo.GetNoteCount(ctx) +} diff --git a/dendrite b/dendrite index 084b912..ade3ffa 100755 Binary files a/dendrite and b/dendrite differ diff --git a/persistence/repositories/index_repository.go b/persistence/repositories/index_repository.go index edf32f4..e587a0c 100644 --- a/persistence/repositories/index_repository.go +++ b/persistence/repositories/index_repository.go @@ -10,11 +10,12 @@ type IIndexRepository interface { WipeIndex(ctx context.Context, dbContext persistence.IDbContext) error } -type indexRepository struct{ +type indexRepository struct { + readDBContext persistence.ReadContext } -func NewIndexRepository() IIndexRepository { - return &indexRepository{} +func NewIndexRepository(rdb persistence.ReadContext) IIndexRepository { + return &indexRepository{readDBContext: rdb} } func (r *indexRepository) WipeIndex(ctx context.Context, dbContext persistence.IDbContext) error { diff --git a/persistence/repositories/note_repository.go b/persistence/repositories/note_repository.go index d73a787..c700e51 100644 --- a/persistence/repositories/note_repository.go +++ b/persistence/repositories/note_repository.go @@ -14,14 +14,15 @@ type INoteRepository interface { InsertRange(ctx context.Context, dbContext persistence.IDbContext, note []*models.Note) error Update(ctx context.Context, dbContext persistence.IDbContext, noteID, path, title, slug string) error GetBySlug(ctx context.Context, slug string) (*models.Note, error) + GetNoteCount(ctx context.Context) (int, error) } type noteRepository struct { readDBContext persistence.ReadContext } -func NewNoteRepository(persistence.ReadContext) INoteRepository { - return ¬eRepository{} +func NewNoteRepository(rdb persistence.ReadContext) INoteRepository { + return ¬eRepository{readDBContext: rdb} } func (r *noteRepository) Insert(ctx context.Context, dbContext persistence.IDbContext, note *models.Note) error { @@ -82,3 +83,16 @@ func (r *noteRepository) GetBySlug(ctx context.Context, slug string) (*models.No return models.NewNote(id, path, title, slug, createdAt, updatedAt), nil } + +func (r *noteRepository) GetNoteCount(ctx context.Context) (int, error) { + query := `SELECT COUNT(*) FROM note` + row := r.readDBContext.QueryRowContext(ctx, query) + + var count int + err := row.Scan(&count) + if err != nil { + return 0, err + } + + return count, nil +}