mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-07-27 13:57:46 +00:00
New common interface for PackgeCollection & PackageList: PackageCatalog. #80
This commit is contained in:
+18
@@ -41,6 +41,7 @@ type PackageList struct {
|
|||||||
// Verify interface
|
// Verify interface
|
||||||
var (
|
var (
|
||||||
_ sort.Interface = &PackageList{}
|
_ sort.Interface = &PackageList{}
|
||||||
|
_ PackageCatalog = &PackageList{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewPackageList creates empty package list
|
// NewPackageList creates empty package list
|
||||||
@@ -356,6 +357,23 @@ func (l *PackageList) Scan(q PackageQuery) (result *PackageList) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SearchSupported returns true for PackageList
|
||||||
|
func (l *PackageList) SearchSupported() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchByKey looks up package by exact key reference
|
||||||
|
func (l *PackageList) SearchByKey(arch, name, version string) (result *PackageList) {
|
||||||
|
result = NewPackageList()
|
||||||
|
|
||||||
|
pkg := l.packages["P"+arch+" "+name+" "+version]
|
||||||
|
if pkg != nil {
|
||||||
|
result.Add(pkg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Search searches package index for specified package(s) using optimized queries
|
// Search searches package index for specified package(s) using optimized queries
|
||||||
func (l *PackageList) Search(dep Dependency, allMatches bool) (searchResults []*Package) {
|
func (l *PackageList) Search(dep Dependency, allMatches bool) (searchResults []*Package) {
|
||||||
if !l.indexed {
|
if !l.indexed {
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ type PackageCollection struct {
|
|||||||
codecHandle *codec.MsgpackHandle
|
codecHandle *codec.MsgpackHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify interface
|
||||||
|
var (
|
||||||
|
_ PackageCatalog = &PackageCollection{}
|
||||||
|
)
|
||||||
|
|
||||||
// NewPackageCollection creates new PackageCollection and binds it to database
|
// NewPackageCollection creates new PackageCollection and binds it to database
|
||||||
func NewPackageCollection(db database.Storage) *PackageCollection {
|
func NewPackageCollection(db database.Storage) *PackageCollection {
|
||||||
return &PackageCollection{
|
return &PackageCollection{
|
||||||
@@ -237,3 +242,49 @@ func (collection *PackageCollection) DeleteByKey(key []byte) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scan does full scan on all the packages
|
||||||
|
func (collection *PackageCollection) Scan(q PackageQuery) (result *PackageList) {
|
||||||
|
result = NewPackageList()
|
||||||
|
|
||||||
|
for _, key := range collection.db.KeysByPrefix([]byte("P")) {
|
||||||
|
pkg, err := collection.ByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("unable to load package: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if q.Matches(pkg) {
|
||||||
|
result.Add(pkg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search is not implemented
|
||||||
|
func (collection *PackageCollection) Search(dep Dependency, allMatches bool) (searchResults []*Package) {
|
||||||
|
panic("Not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchSupported returns false
|
||||||
|
func (collection *PackageCollection) SearchSupported() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SearchByKey finds package by exact key
|
||||||
|
func (collection *PackageCollection) SearchByKey(arch, name, version string) (result *PackageList) {
|
||||||
|
result = NewPackageList()
|
||||||
|
|
||||||
|
for _, key := range collection.db.KeysByPrefix([]byte(fmt.Sprintf("P%s %s %s", arch, name, version))) {
|
||||||
|
pkg, err := collection.ByKey(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("unable to load package: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if pkg.Architecture == arch && pkg.Name == name && pkg.Version == version {
|
||||||
|
result.Add(pkg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
+36
-31
@@ -7,14 +7,22 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PackageCatalog is abstraction on top of PackageCollection and PackageList
|
||||||
|
type PackageCatalog interface {
|
||||||
|
Scan(q PackageQuery) (result *PackageList)
|
||||||
|
Search(dep Dependency, allMatches bool) (searchResults []*Package)
|
||||||
|
SearchSupported() bool
|
||||||
|
SearchByKey(arch, name, version string) (result *PackageList)
|
||||||
|
}
|
||||||
|
|
||||||
// PackageQuery is interface of predicate on Package
|
// PackageQuery is interface of predicate on Package
|
||||||
type PackageQuery interface {
|
type PackageQuery interface {
|
||||||
// Matches calculates match of condition against package
|
// Matches calculates match of condition against package
|
||||||
Matches(pkg *Package) bool
|
Matches(pkg *Package) bool
|
||||||
// Fast returns if search strategy is possible for this query
|
// Fast returns if search strategy is possible for this query
|
||||||
Fast() bool
|
Fast(list PackageCatalog) bool
|
||||||
// Query performs search on package list
|
// Query performs search on package list
|
||||||
Query(list *PackageList) *PackageList
|
Query(list PackageCatalog) *PackageList
|
||||||
// String interface
|
// String interface
|
||||||
String() string
|
String() string
|
||||||
}
|
}
|
||||||
@@ -60,13 +68,13 @@ func (q *OrQuery) Matches(pkg *Package) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fast is true only if both parts are fast
|
// Fast is true only if both parts are fast
|
||||||
func (q *OrQuery) Fast() bool {
|
func (q *OrQuery) Fast(list PackageCatalog) bool {
|
||||||
return q.L.Fast() && q.R.Fast()
|
return q.L.Fast(list) && q.R.Fast(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query strategy depends on nodes
|
// Query strategy depends on nodes
|
||||||
func (q *OrQuery) Query(list *PackageList) (result *PackageList) {
|
func (q *OrQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
if q.Fast() {
|
if q.Fast(list) {
|
||||||
result = q.L.Query(list)
|
result = q.L.Query(list)
|
||||||
result.Append(q.R.Query(list))
|
result.Append(q.R.Query(list))
|
||||||
} else {
|
} else {
|
||||||
@@ -86,16 +94,16 @@ func (q *AndQuery) Matches(pkg *Package) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fast is true if any of the parts are fast
|
// Fast is true if any of the parts are fast
|
||||||
func (q *AndQuery) Fast() bool {
|
func (q *AndQuery) Fast(list PackageCatalog) bool {
|
||||||
return q.L.Fast() || q.R.Fast()
|
return q.L.Fast(list) || q.R.Fast(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query strategy depends on nodes
|
// Query strategy depends on nodes
|
||||||
func (q *AndQuery) Query(list *PackageList) (result *PackageList) {
|
func (q *AndQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
if !q.Fast() {
|
if !q.Fast(list) {
|
||||||
result = list.Scan(q)
|
result = list.Scan(q)
|
||||||
} else {
|
} else {
|
||||||
if q.L.Fast() {
|
if q.L.Fast(list) {
|
||||||
result = q.L.Query(list)
|
result = q.L.Query(list)
|
||||||
result = result.Scan(q.R)
|
result = result.Scan(q.R)
|
||||||
} else {
|
} else {
|
||||||
@@ -117,12 +125,12 @@ func (q *NotQuery) Matches(pkg *Package) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fast is false
|
// Fast is false
|
||||||
func (q *NotQuery) Fast() bool {
|
func (q *NotQuery) Fast(list PackageCatalog) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query strategy is scan always
|
// Query strategy is scan always
|
||||||
func (q *NotQuery) Query(list *PackageList) (result *PackageList) {
|
func (q *NotQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
result = list.Scan(q)
|
result = list.Scan(q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -170,13 +178,13 @@ func (q *FieldQuery) Matches(pkg *Package) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Query runs iteration through list
|
// Query runs iteration through list
|
||||||
func (q *FieldQuery) Query(list *PackageList) (result *PackageList) {
|
func (q *FieldQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
result = list.Scan(q)
|
result = list.Scan(q)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast depends on the query
|
// Fast depends on the query
|
||||||
func (q *FieldQuery) Fast() bool {
|
func (q *FieldQuery) Fast(list PackageCatalog) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,15 +223,19 @@ func (q *DependencyQuery) Matches(pkg *Package) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fast is always true for dependency query
|
// Fast is always true for dependency query
|
||||||
func (q *DependencyQuery) Fast() bool {
|
func (q *DependencyQuery) Fast(list PackageCatalog) bool {
|
||||||
return true
|
return list.SearchSupported()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query runs PackageList.Search
|
// Query runs PackageList.Search
|
||||||
func (q *DependencyQuery) Query(list *PackageList) (result *PackageList) {
|
func (q *DependencyQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
result = NewPackageList()
|
if q.Fast(list) {
|
||||||
for _, pkg := range list.Search(q.Dep, true) {
|
result = NewPackageList()
|
||||||
result.Add(pkg)
|
for _, pkg := range list.Search(q.Dep, true) {
|
||||||
|
result.Add(pkg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = list.Scan(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -240,20 +252,13 @@ func (q *PkgQuery) Matches(pkg *Package) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fast is always true for package query
|
// Fast is always true for package query
|
||||||
func (q *PkgQuery) Fast() bool {
|
func (q *PkgQuery) Fast(list PackageCatalog) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query looks up specific package
|
// Query looks up specific package
|
||||||
func (q *PkgQuery) Query(list *PackageList) (result *PackageList) {
|
func (q *PkgQuery) Query(list PackageCatalog) (result *PackageList) {
|
||||||
result = NewPackageList()
|
return list.SearchByKey(q.Arch, q.Pkg, q.Version)
|
||||||
|
|
||||||
pkg := list.packages["P"+q.Arch+" "+q.Pkg+" "+q.Version]
|
|
||||||
if pkg != nil {
|
|
||||||
result.Add(pkg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// String interface
|
// String interface
|
||||||
|
|||||||
Reference in New Issue
Block a user