feat(storage): add --backend flag for Dolt backend selection
Phase 2 of Dolt integration - enables runtime backend selection: - Add --backend flag to bd init (sqlite|dolt) - Create storage factory for backend instantiation - Update daemon and main.go to use factory with config detection - Update database discovery to find Dolt backends via metadata.json - Fix Dolt schema init to split statements for MySQL compatibility - Add ReadOnly mode to skip schema init for read-only commands Usage: bd init --backend dolt --prefix myproject Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
gastown/crew/dennis
parent
e861a667fc
commit
669ea40684
86
internal/storage/factory/factory.go
Normal file
86
internal/storage/factory/factory.go
Normal file
@@ -0,0 +1,86 @@
|
||||
// Package factory provides functions for creating storage backends based on configuration.
|
||||
package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/steveyegge/beads/internal/configfile"
|
||||
"github.com/steveyegge/beads/internal/storage"
|
||||
"github.com/steveyegge/beads/internal/storage/dolt"
|
||||
"github.com/steveyegge/beads/internal/storage/sqlite"
|
||||
)
|
||||
|
||||
// Options configures how the storage backend is opened
|
||||
type Options struct {
|
||||
ReadOnly bool
|
||||
LockTimeout time.Duration
|
||||
}
|
||||
|
||||
// New creates a storage backend based on the backend type.
|
||||
// For SQLite, path should be the full path to the .db file.
|
||||
// For Dolt, path should be the directory containing the Dolt database.
|
||||
func New(ctx context.Context, backend, path string) (storage.Storage, error) {
|
||||
return NewWithOptions(ctx, backend, path, Options{})
|
||||
}
|
||||
|
||||
// NewWithOptions creates a storage backend with the specified options.
|
||||
func NewWithOptions(ctx context.Context, backend, path string, opts Options) (storage.Storage, error) {
|
||||
switch backend {
|
||||
case configfile.BackendSQLite, "":
|
||||
if opts.ReadOnly {
|
||||
if opts.LockTimeout > 0 {
|
||||
return sqlite.NewReadOnlyWithTimeout(ctx, path, opts.LockTimeout)
|
||||
}
|
||||
return sqlite.NewReadOnly(ctx, path)
|
||||
}
|
||||
if opts.LockTimeout > 0 {
|
||||
return sqlite.NewWithTimeout(ctx, path, opts.LockTimeout)
|
||||
}
|
||||
return sqlite.New(ctx, path)
|
||||
case configfile.BackendDolt:
|
||||
return dolt.New(ctx, &dolt.Config{Path: path, ReadOnly: opts.ReadOnly})
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown storage backend: %s (supported: sqlite, dolt)", backend)
|
||||
}
|
||||
}
|
||||
|
||||
// NewFromConfig creates a storage backend based on the metadata.json configuration.
|
||||
// beadsDir is the path to the .beads directory.
|
||||
func NewFromConfig(ctx context.Context, beadsDir string) (storage.Storage, error) {
|
||||
return NewFromConfigWithOptions(ctx, beadsDir, Options{})
|
||||
}
|
||||
|
||||
// NewFromConfigWithOptions creates a storage backend with options from metadata.json.
|
||||
func NewFromConfigWithOptions(ctx context.Context, beadsDir string, opts Options) (storage.Storage, error) {
|
||||
cfg, err := configfile.Load(beadsDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading config: %w", err)
|
||||
}
|
||||
if cfg == nil {
|
||||
cfg = configfile.DefaultConfig()
|
||||
}
|
||||
|
||||
backend := cfg.GetBackend()
|
||||
switch backend {
|
||||
case configfile.BackendSQLite:
|
||||
return NewWithOptions(ctx, backend, cfg.DatabasePath(beadsDir), opts)
|
||||
case configfile.BackendDolt:
|
||||
// For Dolt, use a subdirectory to store the Dolt database
|
||||
doltPath := filepath.Join(beadsDir, "dolt")
|
||||
return NewWithOptions(ctx, backend, doltPath, opts)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown storage backend in config: %s", backend)
|
||||
}
|
||||
}
|
||||
|
||||
// GetBackendFromConfig returns the backend type from metadata.json
|
||||
func GetBackendFromConfig(beadsDir string) string {
|
||||
cfg, err := configfile.Load(beadsDir)
|
||||
if err != nil || cfg == nil {
|
||||
return configfile.BackendSQLite
|
||||
}
|
||||
return cfg.GetBackend()
|
||||
}
|
||||
Reference in New Issue
Block a user