feat(db_context): added db context

This commit is contained in:
Kristian Borgwarth 2026-04-04 00:14:58 +02:00
parent d6811e4ac1
commit 566ba834d4
9 changed files with 72 additions and 22 deletions

View file

@ -18,10 +18,12 @@ type createNoteCommand struct {
Vars map[string]string `json:"vars"` Vars map[string]string `json:"vars"`
} }
type CreateNoteHandler struct{} type CreateNoteHandler struct{
uow *repositories.UnitOfWork
}
func NewCreateNoteHandler() *CreateNoteHandler { func NewCreateNoteHandler() *CreateNoteHandler {
return &CreateNoteHandler{} return &CreateNoteHandler{repositories.NewUnitOfWork()}
} }
func (h *CreateNoteHandler) Handle(ctx context.Context, uow *repositories.UnitOfWork, raw json.RawMessage) (any, error) { func (h *CreateNoteHandler) Handle(ctx context.Context, uow *repositories.UnitOfWork, raw json.RawMessage) (any, error) {

View file

@ -17,13 +17,13 @@ func NewInitializeHandler() *InitializeHandler {
} }
func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) { func (h InitializeHandler) Handle(ctx context.Context, raw json.RawMessage) (any, error) {
var params initializeCommand var cmd initializeCommand
if err := json.Unmarshal(raw, &params); err != nil { if err := json.Unmarshal(raw, &cmd); err != nil {
return nil, err return nil, err
} }
_, err := persistence.InitializeIndex(params.VaultPath) err := persistence.InitializeDBContext(cmd.VaultPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -4,7 +4,6 @@ package server
import ( import (
"bufio" "bufio"
"context" "context"
"database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -14,7 +13,6 @@ import (
) )
type Server struct { type Server struct {
db *sql.DB
handlers map[string]handlers.Handler handlers map[string]handlers.Handler
} }
@ -75,9 +73,6 @@ func (s *Server) handle(w io.Writer, req rpc.Request) {
s.respond(w, req.ID, result, nil) s.respond(w, req.ID, result, nil)
} }
func (s *Server) initalize(){
}
func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) { func (s *Server) respond(w io.Writer, id *int, result any, err *rpc.Error) {
resultJSON, _ := json.Marshal(result) resultJSON, _ := json.Marshal(result)
resp := rpc.Response{ resp := rpc.Response{

3
go.mod
View file

@ -5,9 +5,12 @@ go 1.26
require ( require (
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.11.1 github.com/stretchr/testify v1.11.1
golang.org/x/tools v0.42.0
modernc.org/sqlite v1.47.0 modernc.org/sqlite v1.47.0
) )
require github.com/yuin/goldmark v1.4.13 // indirect
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect

2
go.sum
View file

@ -18,6 +18,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=

38
persistence/db_context.go Normal file
View file

@ -0,0 +1,38 @@
package persistence
import (
"database/sql"
)
type DBContext struct {
DB *sql.DB
}
var dbContext *DBContext
func InitializeDBContext(vaultPath string) (error) {
db, err := InitializeIndex(vaultPath)
if err != nil {
return err
}
dbContext = &DBContext{DB: db}
return nil
}
func GetDBContext() (*DBContext, error) {
if dbContext == nil {
panic("DBContext is not initialized. Call InitializeDbContext first.")
}
return dbContext, nil
}
func CloseDBContext() error {
if dbContext == nil {
return nil
}
err := dbContext.DB.Close()
dbContext = nil
return err
}

View file

@ -3,21 +3,26 @@ package repositories
import ( import (
"database/sql" "database/sql"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence"
"github.com/KristianJBorgwarth/dendrite.daemon/persistence/store" "github.com/KristianJBorgwarth/dendrite.daemon/persistence/store"
) )
type UnitOfWork struct { type UnitOfWork struct {
db *sql.DB dbContext *sql.DB
Transaction *sql.Tx Transaction *sql.Tx
FileStore *store.FileStore FileStore *store.FileStore
} }
func NewUnitOfWork(db *sql.DB) *UnitOfWork { func NewUnitOfWork() *UnitOfWork {
return &UnitOfWork{db: db, FileStore: store.NewFileStore()} db, err := persistence.GetDBContext()
if err != nil {
panic("failed to get DB context: " + err.Error())
}
return &UnitOfWork{dbContext: db.DB, FileStore: store.NewFileStore()}
} }
func (u *UnitOfWork) Begin() (tx *sql.Tx, err error) { func (u *UnitOfWork) Begin() (tx *sql.Tx, err error) {
tx, err = u.db.Begin() tx, err = u.dbContext.Begin()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -16,7 +16,7 @@ import (
func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T) { func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T) {
// Arrange // Arrange
handler := handlers.NewCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB) uow := repositories.NewUnitOfWork()
notePath := filepath.Join(t.TempDir(), "my-note.md") notePath := filepath.Join(t.TempDir(), "my-note.md")
params, _ := json.Marshal(map[string]any{ params, _ := json.Marshal(map[string]any{
"title": "My Note", "title": "My Note",
@ -41,7 +41,7 @@ func TestCreateNoteHandler_NoTemplate_CreatesNoteFileAndReturnsPath(t *testing.T
func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t *testing.T) { func TestCreateNoteHandler_WithTemplate_CreatesNoteFileWithTagsAndReturnsPath(t *testing.T) {
// Arrange // Arrange
handler := handlers.NewCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB) uow := repositories.NewUnitOfWork()
dir := t.TempDir() dir := t.TempDir()
templatePath := filepath.Join(dir, "template.md") templatePath := filepath.Join(dir, "template.md")
@ -85,8 +85,8 @@ func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) {
// Arrange // Arrange
dir := t.TempDir() dir := t.TempDir()
handler := handlers.NewCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uowInit := repositories.NewUnitOfWork(Fixture.DB) uowInit := repositories.NewUnitOfWork()
secondUow := repositories.NewUnitOfWork(Fixture.DB) secondUow := repositories.NewUnitOfWork()
path1 := filepath.Join(dir, "dup-note.md") path1 := filepath.Join(dir, "dup-note.md")
params1, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path1}) params1, _ := json.Marshal(map[string]any{"title": "Dup Note", "path": path1})
@ -114,7 +114,7 @@ func TestCreateNoteHandler_DuplicateSlug_Upserts(t *testing.T) {
func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) { func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) {
// Arrange // Arrange
handler := handlers.NewCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB) uow := repositories.NewUnitOfWork()
// Act // Act
_, err := handler.Handle(Fixture.TestContext, uow, json.RawMessage(`{invalid json}`)) _, err := handler.Handle(Fixture.TestContext, uow, json.RawMessage(`{invalid json}`))
@ -126,7 +126,7 @@ func TestCreateNoteHandler_InvalidJSON_ReturnsError(t *testing.T) {
func TestCreateNoteHandler_NonExistentTemplatePath_ReturnsError(t *testing.T) { func TestCreateNoteHandler_NonExistentTemplatePath_ReturnsError(t *testing.T) {
// Arrange // Arrange
handler := handlers.NewCreateNoteHandler() handler := handlers.NewCreateNoteHandler()
uow := repositories.NewUnitOfWork(Fixture.DB) uow := repositories.NewUnitOfWork()
params, _ := json.Marshal(map[string]any{ params, _ := json.Marshal(map[string]any{
"title": "Ghost Note", "title": "Ghost Note",
"path": filepath.Join(t.TempDir(), "ghost.md"), "path": filepath.Join(t.TempDir(), "ghost.md"),

View file

@ -22,15 +22,20 @@ type DBFixture struct {
func NewDBFixture() *DBFixture { func NewDBFixture() *DBFixture {
vaultPath := os.TempDir() vaultPath := os.TempDir()
db, err := persistence.InitializeIndex(vaultPath) err := persistence.InitializeDBContext(vaultPath)
if err != nil { if err != nil {
panic(err) panic(err)
} }
dbPath := filepath.Join(os.TempDir(), ".index", "index.db") dbPath := filepath.Join(os.TempDir(), ".index", "index.db")
dbContext, err := persistence.GetDBContext()
if err != nil {
panic("failed to get DB context: " + err.Error())
}
return &DBFixture{ return &DBFixture{
DB: db, DB: dbContext.DB,
DBPath: dbPath, DBPath: dbPath,
TestContext: context.Background(), TestContext: context.Background(),
} }