fix(dolt): proper server mode support for routing and storage

- FindDatabasePath now handles Dolt server mode (no local dir required)
- main.go uses NewFromConfigWithOptions for Dolt to read server settings
- Routing uses factory via callback to respect backend configuration
- Handle Dolt "database exists" error (error 1007) gracefully

Previously, Dolt server mode failed because:
1. FindDatabasePath required a local directory to exist
2. main.go bypassed server mode config when creating Dolt storage
3. Routing always opened SQLite regardless of backend config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beads/crew/emma
2026-01-24 00:26:23 -08:00
committed by Steve Yegge
parent 13c362e67e
commit e82f5136c1
5 changed files with 71 additions and 41 deletions

View File

@@ -425,12 +425,27 @@ func (rs *RoutedStorage) Close() error {
return nil
}
// StorageOpener is a function that opens storage for a given beads directory.
// This allows callers to provide custom storage opening logic (e.g., using factory).
type StorageOpener func(ctx context.Context, beadsDir string) (storage.Storage, error)
// GetRoutedStorageForID returns a storage connection for the given issue ID.
// If the ID matches a route, it opens a connection to the routed database using SQLite.
// Otherwise, it returns nil (caller should use their existing storage).
//
// DEPRECATED: Use GetRoutedStorageWithOpener for proper backend support.
// The caller is responsible for closing the returned RoutedStorage.
func GetRoutedStorageForID(ctx context.Context, id, currentBeadsDir string) (*RoutedStorage, error) {
return GetRoutedStorageWithOpener(ctx, id, currentBeadsDir, nil)
}
// GetRoutedStorageWithOpener returns a storage connection for the given issue ID.
// If the ID matches a route, it opens a connection to the routed database.
// The opener function is used to create storage; if nil, defaults to SQLite.
// Otherwise, it returns nil (caller should use their existing storage).
//
// The caller is responsible for closing the returned RoutedStorage.
func GetRoutedStorageForID(ctx context.Context, id, currentBeadsDir string) (*RoutedStorage, error) {
func GetRoutedStorageWithOpener(ctx context.Context, id, currentBeadsDir string, opener StorageOpener) (*RoutedStorage, error) {
beadsDir, routed, err := ResolveBeadsDirForID(ctx, id, currentBeadsDir)
if err != nil {
return nil, err
@@ -441,8 +456,14 @@ func GetRoutedStorageForID(ctx context.Context, id, currentBeadsDir string) (*Ro
}
// Open storage for the routed directory
dbPath := filepath.Join(beadsDir, "beads.db")
store, err := sqlite.New(ctx, dbPath)
var store storage.Storage
if opener != nil {
store, err = opener(ctx, beadsDir)
} else {
// Default to SQLite for backward compatibility
dbPath := filepath.Join(beadsDir, "beads.db")
store, err = sqlite.New(ctx, dbPath)
}
if err != nil {
return nil, err
}