feat(dbcontex): add read context (#18)

This commit is contained in:
Kristian 2026-04-11 15:24:15 +02:00 committed by GitHub
parent f5f0204147
commit 0219248db7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 65 additions and 30 deletions

View file

@ -40,15 +40,15 @@ func (h *CreateNoteHandler) Handle(ctx context.Context, raw json.RawMessage) (an
notePath := filepath.Join(store.GetVaultStore().Config.VaultPath(), cmd.Directory, template.Slug+".md")
tx, err := h.uow.Begin()
dbCtx, err := h.uow.Begin()
if err != nil {
return nil, err
}
defer h.uow.Rollback()
tagRepo := repositories.NewTagRepository(tx)
noteRepo := repositories.NewNoteRepository(tx)
tagRepo := repositories.NewTagRepository(dbCtx)
noteRepo := repositories.NewNoteRepository(dbCtx)
dbTags, err := tagRepo.GetByNames(ctx, template.FrontMatter.Tags)
if err != nil {

BIN
dendrite

Binary file not shown.

View file

@ -4,11 +4,11 @@ import (
"database/sql"
)
type DBContext struct {
type Database struct {
DB *sql.DB
}
var dbContext *DBContext
var dbContext *Database
func InitializeDBContext(vaultPath string) (error) {
@ -17,11 +17,11 @@ func InitializeDBContext(vaultPath string) (error) {
return err
}
dbContext = &DBContext{DB: db}
dbContext = &Database{DB: db}
return nil
}
func GetDBContext() (*DBContext) {
func GetDBContext() (*Database) {
if dbContext == nil {
panic("DBContext is not initialized. Call InitializeDbContext first.")
}

View file

@ -0,0 +1,12 @@
package persistence
import (
"context"
"database/sql"
)
type IDbContext interface {
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
}

View file

@ -0,0 +1,24 @@
package persistence
import (
"context"
"database/sql"
)
type ReadContext struct{}
func NewReadContext() *ReadContext {
return &ReadContext{}
}
func (r *ReadContext) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) {
return GetDBContext().DB.ExecContext(ctx, query, args...)
}
func (r *ReadContext) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) {
return GetDBContext().DB.QueryContext(ctx, query, args...)
}
func (r *ReadContext) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row {
return GetDBContext().DB.QueryRowContext(ctx, query, args...)
}

View file

@ -2,9 +2,9 @@ package repositories
import (
"context"
"database/sql"
"github.com/KristianJBorgwarth/dendrite.daemon/core/models"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
)
type ILinkRepository interface {
@ -14,15 +14,15 @@ type ILinkRepository interface {
}
type linkRepository struct {
Transaction *sql.Tx
dbContext persistence.IDbContext
}
func NewLinkRepository(tx *sql.Tx) ILinkRepository {
return &linkRepository{Transaction: tx}
func NewLinkRepository(ctx persistence.IDbContext) ILinkRepository {
return &linkRepository{dbContext: ctx}
}
func (r *linkRepository) GetByNoteID(ctx context.Context, fromNoteID string) ([]*models.Link, error) {
rows, err := r.Transaction.QueryContext(ctx, "SELECT id, from_note_id, target_slug, raw, display, line, col FROM links WHERE from_note_id = ?", fromNoteID)
rows, err := r.dbContext.QueryContext(ctx, "SELECT id, from_note_id, target_slug, raw, display, line, col FROM links WHERE from_note_id = ?", fromNoteID)
if err != nil {
return nil, err
}
@ -42,7 +42,7 @@ func (r *linkRepository) GetByNoteID(ctx context.Context, fromNoteID string) ([]
}
func (r *linkRepository) GetBySlug(ctx context.Context, targetSlug string) ([]*models.Link, error) {
rows, err := r.Transaction.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM links WHERE target_slug = ?`, targetSlug)
rows, err := r.dbContext.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM links WHERE target_slug = ?`, targetSlug)
if err != nil {
return nil, err
}
@ -62,7 +62,7 @@ func (r *linkRepository) GetBySlug(ctx context.Context, targetSlug string) ([]*m
}
func (r *linkRepository) Search(ctx context.Context, query string) ([]*models.Link, error) {
rows, err := r.Transaction.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM links WHERE raw LIKE ?`, "%"+query+"%")
rows, err := r.dbContext.QueryContext(ctx, `SELECT id, from_note_id, target_slug, raw, display, line, col FROM links WHERE raw LIKE ?`, "%"+query+"%")
if err != nil {
return nil, err
}

View file

@ -2,9 +2,9 @@ package repositories
import (
"context"
"database/sql"
"github.com/KristianJBorgwarth/dendrite.daemon/core/models"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
)
type NoteRepository interface {
@ -13,11 +13,11 @@ type NoteRepository interface {
}
type noteRepository struct {
Transaction *sql.Tx
dbContext persistence.IDbContext
}
func NewNoteRepository(tx *sql.Tx) NoteRepository {
return &noteRepository{Transaction: tx}
func NewNoteRepository(ctx persistence.IDbContext) NoteRepository {
return &noteRepository{dbContext: ctx}
}
func (r *noteRepository) Insert(ctx context.Context, note *models.Note) error {
@ -28,13 +28,13 @@ func (r *noteRepository) Insert(ctx context.Context, note *models.Note) error {
SET title = EXCLUDED.title,
path = EXCLUDED.path;
`
_, err := r.Transaction.ExecContext(ctx, query, note.ID(), note.Title(), note.Path(), note.Slug())
_, err := r.dbContext.ExecContext(ctx, query, note.ID(), note.Title(), note.Path(), note.Slug())
return err
}
func (r *noteRepository) GetBySlug(ctx context.Context, slug string) (*models.Note, error) {
query := `SELECT id, title, path, slug, created_at, updated_at FROM notes WHERE slug = ?`
row := r.Transaction.QueryRowContext(ctx, query, slug)
row := r.dbContext.QueryRowContext(ctx, query, slug)
var id, title, path, createdAt, updatedAt string
err := row.Scan(&id, &title, &path, &slug, &createdAt, &updatedAt)

View file

@ -2,10 +2,10 @@ package repositories
import (
"context"
"database/sql"
"strings"
"github.com/KristianJBorgwarth/dendrite.daemon/core/models"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
)
type ITagRepository interface {
@ -15,11 +15,11 @@ type ITagRepository interface {
}
type tagRepository struct {
Transaction *sql.Tx
dbContext persistence.IDbContext
}
func NewTagRepository(tx *sql.Tx) ITagRepository {
return &tagRepository{Transaction: tx}
func NewTagRepository(ctx persistence.IDbContext) ITagRepository {
return &tagRepository{dbContext: ctx}
}
func (r *tagRepository) Insert(ctx context.Context, tags []*models.Tag) error {
@ -37,7 +37,7 @@ 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.Transaction.ExecContext(ctx, query, args...)
_, err := r.dbContext.ExecContext(ctx, query, args...)
return err
}
@ -56,7 +56,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.Transaction.ExecContext(ctx, query, args...)
_, err := r.dbContext.ExecContext(ctx, query, args...)
if err != nil {
return err
}
@ -79,7 +79,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.Transaction.QueryContext(ctx, query, args...)
rows, err := r.dbContext.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
}

View file

@ -16,9 +16,8 @@ func NewUnitOfWork() *UnitOfWork {
return &UnitOfWork{FileStore: store.NewFileStore()}
}
func (u *UnitOfWork) Begin() (tx *sql.Tx, err error) {
dbContext := persistence.GetDBContext()
tx, err = dbContext.DB.Begin()
func (u *UnitOfWork) Begin() (persistence.IDbContext, error) {
tx, err := persistence.GetDBContext().DB.Begin()
if err != nil {
return nil, err
}