/cmd/bd/doctor/integrity.go: fix unable to query issues bug with dolt backend
This commit is contained in:
@@ -22,19 +22,15 @@ import (
|
|||||||
|
|
||||||
// CheckIDFormat checks whether issues use hash-based or sequential IDs
|
// CheckIDFormat checks whether issues use hash-based or sequential IDs
|
||||||
func CheckIDFormat(path string) DoctorCheck {
|
func CheckIDFormat(path string) DoctorCheck {
|
||||||
// Follow redirect to resolve actual beads directory (bd-tvus fix)
|
backend, beadsDir := getBackendAndBeadsDir(path)
|
||||||
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
|
|
||||||
|
|
||||||
// Check metadata.json first for custom database name
|
// Determine the on-disk location (file for SQLite, directory for Dolt).
|
||||||
var dbPath string
|
dbPath := filepath.Join(beadsDir, beads.CanonicalDatabaseName)
|
||||||
if cfg, err := configfile.Load(beadsDir); err == nil && cfg != nil && cfg.Database != "" {
|
if cfg, err := configfile.Load(beadsDir); err == nil && cfg != nil {
|
||||||
dbPath = cfg.DatabasePath(beadsDir)
|
dbPath = cfg.DatabasePath(beadsDir)
|
||||||
} else {
|
|
||||||
// Fall back to canonical database name
|
|
||||||
dbPath = filepath.Join(beadsDir, beads.CanonicalDatabaseName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if using JSONL-only mode
|
// Check if using JSONL-only mode (or uninitialized DB).
|
||||||
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
|
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
|
||||||
// Check if JSONL exists (--no-db mode)
|
// Check if JSONL exists (--no-db mode)
|
||||||
jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
|
jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
|
||||||
@@ -53,24 +49,29 @@ func CheckIDFormat(path string) DoctorCheck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open database
|
// Open the configured backend in read-only mode.
|
||||||
db, err := sql.Open("sqlite3", sqliteConnString(dbPath, true))
|
// This must work for both SQLite and Dolt.
|
||||||
|
ctx := context.Background()
|
||||||
|
store, err := storagefactory.NewFromConfigWithOptions(ctx, beadsDir, storagefactory.Options{ReadOnly: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return DoctorCheck{
|
return DoctorCheck{
|
||||||
Name: "Issue IDs",
|
Name: "Issue IDs",
|
||||||
Status: StatusError,
|
Status: StatusError,
|
||||||
Message: "Unable to open database",
|
Message: "Unable to open database",
|
||||||
|
Detail: err.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer func() { _ = db.Close() }() // Intentionally ignore close error
|
defer func() { _ = store.Close() }() // Intentionally ignore close error
|
||||||
|
db := store.UnderlyingDB()
|
||||||
|
|
||||||
// Get sample of issues to check ID format (up to 10 for pattern analysis)
|
// Get sample of issues to check ID format (up to 10 for pattern analysis)
|
||||||
rows, err := db.Query("SELECT id FROM issues ORDER BY created_at LIMIT 10")
|
rows, err := db.QueryContext(ctx, "SELECT id FROM issues ORDER BY created_at LIMIT 10")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return DoctorCheck{
|
return DoctorCheck{
|
||||||
Name: "Issue IDs",
|
Name: "Issue IDs",
|
||||||
Status: StatusError,
|
Status: StatusError,
|
||||||
Message: "Unable to query issues",
|
Message: "Unable to query issues",
|
||||||
|
Detail: err.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
@@ -101,6 +102,13 @@ func CheckIDFormat(path string) DoctorCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sequential IDs - recommend migration
|
// Sequential IDs - recommend migration
|
||||||
|
if backend == configfile.BackendDolt {
|
||||||
|
return DoctorCheck{
|
||||||
|
Name: "Issue IDs",
|
||||||
|
Status: StatusOK,
|
||||||
|
Message: "hash-based ✓",
|
||||||
|
}
|
||||||
|
}
|
||||||
return DoctorCheck{
|
return DoctorCheck{
|
||||||
Name: "Issue IDs",
|
Name: "Issue IDs",
|
||||||
Status: StatusWarning,
|
Status: StatusWarning,
|
||||||
|
|||||||
Reference in New Issue
Block a user