feat: diagnostics links (#39)
* feat(diagnostic/link): retrive broken links * add to main * feat: return array on empty
This commit is contained in:
parent
c0924342fb
commit
70e9f756ea
6 changed files with 109 additions and 3 deletions
|
|
@ -5,6 +5,7 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/completion"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/diagnostics"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/note"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/handlers/vault"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/logging"
|
||||
|
|
@ -44,6 +45,8 @@ func main() {
|
|||
server.RegisterHandler("completion/tag", completion.NewCompleteTagHandler(tagRepo))
|
||||
server.RegisterHandler("completion/slug", completion.NewCompleteSlugHandler(noteRepo))
|
||||
|
||||
server.RegisterHandler("diagnostics/links", diagnostics.NewLinkDiagnosticHandler(noteRepo, linkRepo))
|
||||
|
||||
if err := server.Run(os.Stdin, os.Stdout); err != nil {
|
||||
slog.Error("server error", "error", err)
|
||||
}
|
||||
|
|
|
|||
11
core/dtos/link_diagnostic_dto.go
Normal file
11
core/dtos/link_diagnostic_dto.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package dtos
|
||||
|
||||
type LinkDiagnosticDto struct {
|
||||
NoteID string `json:"noteId"`
|
||||
NotePath string `json:"notePath"`
|
||||
Line int `json:"line"`
|
||||
Col int `json:"col"`
|
||||
Raw string `json:"raw"`
|
||||
Target string `json:"target"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
2
core/handlers/diagnostics/doc.go
Normal file
2
core/handlers/diagnostics/doc.go
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
// Package diagnostics provides commands for executing diagnostics against vault entities
|
||||
package diagnostics
|
||||
63
core/handlers/diagnostics/links_diagnostic_handler.go
Normal file
63
core/handlers/diagnostics/links_diagnostic_handler.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
package diagnostics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/dtos"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/core/models"
|
||||
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/repositories"
|
||||
)
|
||||
|
||||
type LinkDiagnosticCommand struct {
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type LinkDiagnosticHandler struct {
|
||||
noteRepository repositories.INoteRepository
|
||||
linkRepository repositories.ILinkRepository
|
||||
}
|
||||
|
||||
func NewLinkDiagnosticHandler(
|
||||
noteRepository repositories.INoteRepository,
|
||||
linkRepository repositories.ILinkRepository,
|
||||
) *LinkDiagnosticHandler {
|
||||
return &LinkDiagnosticHandler{noteRepository, linkRepository}
|
||||
}
|
||||
|
||||
func (h *LinkDiagnosticHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) {
|
||||
var cmd LinkDiagnosticCommand
|
||||
|
||||
if err := json.Unmarshal(raw, &cmd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
note, err := h.noteRepository.GetByPath(ctx, cmd.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
brokenLinks, err := h.linkRepository.GetBrokenLinks(ctx, note.ID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mapToDiagnosticResult(note, brokenLinks), nil
|
||||
}
|
||||
|
||||
func mapToDiagnosticResult(note *models.Note, links []*models.Link) []*dtos.LinkDiagnosticDto {
|
||||
diagnostics := make([]*dtos.LinkDiagnosticDto, 0, len(links))
|
||||
for _, link := range links {
|
||||
diagnostics = append(diagnostics, &dtos.LinkDiagnosticDto{
|
||||
NoteID: link.ID(),
|
||||
NotePath: note.Path(),
|
||||
Line: link.Line(),
|
||||
Col: link.Col(),
|
||||
Raw: link.Raw(),
|
||||
Target: link.TargetSlug(),
|
||||
Message: "Broken link: target note does not exist",
|
||||
})
|
||||
}
|
||||
|
||||
return diagnostics
|
||||
}
|
||||
BIN
dendrite
BIN
dendrite
Binary file not shown.
|
|
@ -12,10 +12,11 @@ import (
|
|||
type ILinkRepository interface {
|
||||
Insert(ctx context.Context, dbContext persistence.IDbContext, links []*models.Link) error
|
||||
InsertRange(ctx context.Context, dbContext persistence.IDbContext, links []*models.Link) error
|
||||
GetByNoteID(ctx context.Context, dbContext persistence.IDbContext, fromNoteID string) ([]*models.Link, error)
|
||||
GetByNoteID(ctx context.Context, fromNoteID string) ([]*models.Link, error)
|
||||
GetBySlug(ctx context.Context, dbContext persistence.IDbContext, targetSlug string) ([]*models.Link, error)
|
||||
GetBacklinks(ctx context.Context, slug string) ([]*dtos.BacklinkDto, error)
|
||||
Delete(ctx context.Context, dbContext persistence.IDbContext, fromNoteID string) error
|
||||
GetBrokenLinks(ctx context.Context, fromNoteID string) ([]*models.Link, error)
|
||||
}
|
||||
|
||||
type linkRepository struct {
|
||||
|
|
@ -64,8 +65,8 @@ func (r *linkRepository) InsertRange(ctx context.Context, dbContext persistence.
|
|||
return nil
|
||||
}
|
||||
|
||||
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)
|
||||
func (r *linkRepository) GetByNoteID(ctx context.Context, fromNoteID string) ([]*models.Link, error) {
|
||||
rows, err := r.readDBContext.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
|
||||
}
|
||||
|
|
@ -134,3 +135,29 @@ func (r *linkRepository) Delete(ctx context.Context, dbContext persistence.IDbCo
|
|||
_, err := dbContext.ExecContext(ctx, "DELETE FROM link WHERE from_note_id = ?", fromNoteID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *linkRepository) GetBrokenLinks(ctx context.Context, fromNoteID string) ([]*models.Link, error) {
|
||||
query := `
|
||||
SELECT l.id, l.from_note_id, l.target_slug, l.raw, l.display, l.line, l.col
|
||||
FROM link l
|
||||
LEFT JOIN note n ON l.target_slug = n.slug
|
||||
WHERE l.from_note_id = ? AND n.id IS NULL`
|
||||
|
||||
rows, err := r.readDBContext.QueryContext(ctx, query, fromNoteID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var brokenLinks []*models.Link
|
||||
for rows.Next() {
|
||||
var id, rowFromNoteID, targetSlug, raw, display string
|
||||
var line, col int
|
||||
if err := rows.Scan(&id, &rowFromNoteID, &targetSlug, &raw, &display, &line, &col); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
brokenLinks = append(brokenLinks, models.NewLink(id, fromNoteID, targetSlug, raw, display, line, col))
|
||||
}
|
||||
|
||||
return brokenLinks, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue