mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-06-04 05:10:40 +00:00
Merge pull request #1445 from silkeh/fix-db-references
Remove corrupt package references in `db recover`
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package deb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/aptly-dev/aptly/database"
|
||||
)
|
||||
|
||||
// FindDanglingReferences finds references that exist in the given PackageRefList, but not in the given PackageCollection.
|
||||
// It returns all such references, so they can be removed from the database.
|
||||
func FindDanglingReferences(reflist *PackageRefList, packages *PackageCollection) (dangling *PackageRefList, err error) {
|
||||
dangling = &PackageRefList{}
|
||||
|
||||
err = reflist.ForEach(func(key []byte) error {
|
||||
ok, err := isDangling(packages, key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok {
|
||||
dangling.Refs = append(dangling.Refs, key)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dangling, nil
|
||||
}
|
||||
|
||||
func isDangling(packages *PackageCollection, key []byte) (bool, error) {
|
||||
_, err := packages.ByKey(key)
|
||||
if errors.Is(err, database.ErrNotFound) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("get reference %q: %w", key, err)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package deb_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/aptly-dev/aptly/database/goleveldb"
|
||||
"github.com/aptly-dev/aptly/deb"
|
||||
)
|
||||
|
||||
func TestFindDanglingReferences(t *testing.T) {
|
||||
reflist := deb.NewPackageRefList()
|
||||
reflist.Refs = [][]byte{[]byte("P existing 1.2.3"), []byte("P dangling 1.2.3")}
|
||||
|
||||
db, _ := goleveldb.NewOpenDB(t.TempDir())
|
||||
packages := deb.NewPackageCollection(db)
|
||||
|
||||
if err := packages.Update(&deb.Package{Name: "existing", Version: "1.2.3"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dangling, err := deb.FindDanglingReferences(reflist, packages)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
exp := &deb.PackageRefList{
|
||||
Refs: [][]byte{[]byte("P dangling 1.2.3")},
|
||||
}
|
||||
|
||||
compareRefs(t, exp, dangling)
|
||||
}
|
||||
|
||||
func compareRefs(t *testing.T, exp, got *deb.PackageRefList) {
|
||||
t.Helper()
|
||||
|
||||
if len(exp.Refs) != len(got.Refs) {
|
||||
t.Fatalf("refs length mismatch: exp %d, got %d", len(exp.Refs), len(got.Refs))
|
||||
}
|
||||
|
||||
for i := range exp.Refs {
|
||||
if !bytes.Equal(exp.Refs[i], got.Refs[i]) {
|
||||
t.Fatalf("refs do not match: exp %q, got %q", exp.Refs[i], got.Refs[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user