diff --git a/core/handlers/create_note_handler.go b/core/handlers/create_note_handler.go index 10cd3cd..f43fb61 100644 --- a/core/handlers/create_note_handler.go +++ b/core/handlers/create_note_handler.go @@ -3,7 +3,6 @@ package handlers import ( "context" "encoding/json" - "log/slog" "github.com/KristianJBorgwarth/dendrite.daemon/core/frontmatter" "github.com/KristianJBorgwarth/dendrite.daemon/core/models" @@ -13,12 +12,12 @@ import ( ) type createNoteCommand struct { - Title string `json:"title"` - TemplatePath string `json:"templatePath"` - Path string `json:"path"` + Title string `json:"title"` + TemplatePath string `json:"templatePath"` + Path string `json:"path"` } -type CreateNoteHandler struct{ +type CreateNoteHandler struct { uow *repositories.UnitOfWork } @@ -40,15 +39,11 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an return nil, err } - slog.Debug("rendered template", "data", string(data)) - tags, err := frontmatter.ParseTags(data) if err != nil { return nil, err } - slog.Debug("parsed tags", "tags", tags) - tx, err := h.uow.Begin() if err != nil { return nil, err @@ -59,17 +54,31 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an tagRepo := repositories.NewTagRepository(tx) noteRepo := repositories.NewNoteRepository(tx) - tagModels, err := models.CreateTags(tags) + dbTags, err := tagRepo.GetByNames(ctx, tags) if err != nil { return nil, err } - slog.Debug("Creating tags", "tags", tags) + newTags := utils.Filter(tags, func(name string) bool { + for _, t := range dbTags { + if t.Name() == name { + return false + } + } + return true + }) + + tagModels, err := models.CreateTags(newTags) + if err != nil { + return nil, err + } if err = tagRepo.Upsert(ctx, tagModels); err != nil { return nil, err } + tagModels = append(tagModels, dbTags...) + note := models.CreateNote(cmd.Path, cmd.Title, slug) if err = noteRepo.Upsert(ctx, note); err != nil { diff --git a/core/models/tag.go b/core/models/tag.go index 8f6461b..ed1087e 100644 --- a/core/models/tag.go +++ b/core/models/tag.go @@ -7,13 +7,9 @@ type Tag struct { name string } -func NewTag(name string) *Tag { - id, err := uuid.NewV7() - if err != nil { - panic(err) - } +func NewTag(id, name string) *Tag { return &Tag{ - id: id.String(), + id: id, name: name, } } @@ -21,7 +17,11 @@ func NewTag(name string) *Tag { func CreateTags(tags []string) ([]*Tag, error) { tagModels := make([]*Tag, len(tags)) for i, tag := range tags { - tagModels[i] = NewTag(tag) + id, err := uuid.NewV7() + if err != nil { + panic(err) + } + tagModels[i] = NewTag(id.String(), tag) } return tagModels, nil diff --git a/core/utils/doc.go b/core/utils/doc.go index f8b0649..305ba9c 100644 --- a/core/utils/doc.go +++ b/core/utils/doc.go @@ -8,3 +8,13 @@ func Select[T any, U any](input []T, mapper func(T) U) []U { } return output } + +func Filter[T any](input []T, predicate func(T) bool) []T { + output := make([]T, 0) + for _, item := range input { + if predicate(item) { + output = append(output, item) + } + } + return output +} diff --git a/dendrite b/dendrite index ec9a22a..3410aa4 100755 Binary files a/dendrite and b/dendrite differ diff --git a/persistence/repositories/tag_repository.go b/persistence/repositories/tag_repository.go index 4710728..27fcd2f 100644 --- a/persistence/repositories/tag_repository.go +++ b/persistence/repositories/tag_repository.go @@ -11,6 +11,7 @@ import ( type ITagRepository interface { Upsert(ctx context.Context, tags []*models.Tag) error UpsertNoteTags(ctx context.Context, noteID string, tagIDs []string) error + GetByNames(ctx context.Context, names []string) ([]*models.Tag, error) } type tagRepository struct { @@ -62,3 +63,37 @@ func (r *tagRepository) UpsertNoteTags(ctx context.Context ,noteID string, tagID return nil } + +func (r *tagRepository) GetByNames(ctx context.Context, names []string) ([]*models.Tag, error) { + if len(names) == 0 { + return []*models.Tag{}, nil + } + + placeholders := make([]string, 0, len(names)) + args := make([]any, 0, len(names)) + + for _, name := range names { + placeholders = append(placeholders, "?") + args = append(args, name) + } + + query := "SELECT id, name FROM tags WHERE name IN (" + strings.Join(placeholders, ",") + ")" + + rows, err := r.Transaction.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + var tags []*models.Tag + for rows.Next() { + var id string + var name string + if err := rows.Scan(&id, &name); err != nil { + return nil, err + } + tags = append(tags, models.NewTag(id, name)) + } + + return tags, nil +}