fix(sqlite): handle dots in prefix for extractParentChain (GH#664)

extractParentChain was using strings.Split(id, ".") which incorrectly
parsed prefixes containing dots (like "alicealexandra.com"). This caused
--parent to fail with "parent does not exist" even when the parent was
present in the database.

The fix uses IsHierarchicalID to walk up the hierarchy correctly, only
splitting on dots followed by numeric suffixes (the actual hierarchy
delimiter).

Example:
- "test.example-abc.1" now correctly returns ["test.example-abc"]
- Previously it incorrectly returned ["test", "test.example-abc"]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-24 14:39:04 -08:00
parent 25402184a6
commit c28defb710
2 changed files with 38 additions and 10 deletions

View File

@@ -224,16 +224,23 @@ func (s *SQLiteStorage) tryResurrectParentChainWithConn(ctx context.Context, con
// extractParentChain returns all parent IDs in a hierarchical chain, ordered from root to leaf. // extractParentChain returns all parent IDs in a hierarchical chain, ordered from root to leaf.
// Example: "bd-abc.1.2" → ["bd-abc", "bd-abc.1"] // Example: "bd-abc.1.2" → ["bd-abc", "bd-abc.1"]
// Example: "test.example-abc.1" → ["test.example-abc"] (prefix with dot is preserved)
//
// This function uses IsHierarchicalID to correctly handle prefixes containing dots (GH#664).
// It only splits on dots followed by numeric suffixes (the hierarchy delimiter).
func extractParentChain(id string) []string { func extractParentChain(id string) []string {
parts := strings.Split(id, ".") var parents []string
if len(parts) <= 1 { current := id
return nil // No parents (top-level ID)
}
parents := make([]string, 0, len(parts)-1) // Walk up the hierarchy by repeatedly finding the parent
for i := 1; i < len(parts); i++ { for {
parent := strings.Join(parts[:i], ".") isHierarchical, parentID := IsHierarchicalID(current)
parents = append(parents, parent) if !isHierarchical {
break // No more parents
}
// Prepend to build root-to-leaf order
parents = append([]string{parentID}, parents...)
current = parentID
} }
return parents return parents

View File

@@ -446,6 +446,27 @@ func TestExtractParentChain(t *testing.T) {
id: "test-abc.1.2.3", id: "test-abc.1.2.3",
expected: []string{"test-abc", "test-abc.1", "test-abc.1.2"}, expected: []string{"test-abc", "test-abc.1", "test-abc.1.2"},
}, },
// GH#664: Prefixes with dots should be handled correctly
{
name: "prefix with dot - top-level",
id: "test.example-abc",
expected: nil, // No numeric suffix, not hierarchical
},
{
name: "prefix with dot - one level deep",
id: "test.example-abc.1",
expected: []string{"test.example-abc"},
},
{
name: "prefix with dot - two levels deep",
id: "test.example-abc.1.2",
expected: []string{"test.example-abc", "test.example-abc.1"},
},
{
name: "prefix with multiple dots - one level deep",
id: "my.company.project-xyz.1",
expected: []string{"my.company.project-xyz"},
},
} }
for _, tt := range tests { for _, tt := range tests {