зеркало из https://github.com/golang/pkgsite.git
internal/postgres: add GetLatestPackageForPaths
This change adds GetLatestPackageForPaths which returns the latest package associated with each path in a list of strings. This method will eventually be used to get the packages queried by search results. Updates b/124308701 Fixes b/126714352 Change-Id: I2b6e86aec7b5ba82ed0e45db52784d3cde1b8074 Reviewed-on: https://team-review.git.corp.google.com/c/golang/discovery/+/439699 Reviewed-by: Julie Qiu <julieqiu@google.com>
This commit is contained in:
Родитель
af51706d15
Коммит
c2e51712c3
|
@ -393,3 +393,80 @@ func (db *DB) InsertVersion(version *internal.Version) error {
|
|||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetLatestPackageForPaths returns a list of packages that have the latest version that
|
||||
// corresponds to each path specified in the list of paths. The resulting list is
|
||||
// sorted by package path lexicographically. So if multiple packages have the same
|
||||
// path then the package whose module path comes first lexicographically will be
|
||||
// returned.
|
||||
func (db *DB) GetLatestPackageForPaths(paths []string) ([]*internal.Package, error) {
|
||||
var (
|
||||
packages []*internal.Package
|
||||
commitTime, createdAt, updatedAt time.Time
|
||||
path, modulePath, name, synopsis, license, version string
|
||||
)
|
||||
|
||||
query := `
|
||||
SELECT DISTINCT ON (p.path)
|
||||
v.created_at,
|
||||
v.updated_at,
|
||||
p.path,
|
||||
p.module_path,
|
||||
v.version,
|
||||
v.commit_time,
|
||||
v.license,
|
||||
p.name,
|
||||
p.synopsis
|
||||
FROM
|
||||
packages p
|
||||
INNER JOIN
|
||||
versions v
|
||||
ON
|
||||
v.module_path = p.module_path
|
||||
AND v.version = p.version
|
||||
WHERE
|
||||
p.path = $1
|
||||
ORDER BY
|
||||
p.path,
|
||||
p.module_path,
|
||||
v.major DESC,
|
||||
v.minor DESC,
|
||||
v.patch DESC,
|
||||
v.prerelease DESC;`
|
||||
|
||||
anyPaths := fmt.Sprintf("ANY('%s'::text[])", strings.Join(paths, ", "))
|
||||
rows, err := db.Query(query, anyPaths)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("db.Query(%q, %q) returned error: %v", query, anyPaths, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
if err := rows.Scan(&createdAt, &updatedAt, &path, &modulePath, &version, &commitTime, &license, &name, &synopsis); err != nil {
|
||||
return nil, fmt.Errorf("row.Scan(%q, %q, %q, %q, %q, %q, %q, %q, %q): %v",
|
||||
createdAt, updatedAt, path, modulePath, version, commitTime, license, name, synopsis, err)
|
||||
}
|
||||
|
||||
packages = append(packages, &internal.Package{
|
||||
Name: name,
|
||||
Path: path,
|
||||
Synopsis: synopsis,
|
||||
Version: &internal.Version{
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
Module: &internal.Module{
|
||||
Path: modulePath,
|
||||
},
|
||||
Version: version,
|
||||
CommitTime: commitTime,
|
||||
License: license,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, fmt.Errorf("rows.Err() returned error %v", err)
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
}
|
||||
|
|
|
@ -322,6 +322,136 @@ func TestPostgres_GetLatestPackage(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPostgres_GetLatestPackageForPaths(t *testing.T) {
|
||||
teardownTestCase, db := SetupCleanDB(t)
|
||||
defer teardownTestCase(t)
|
||||
var (
|
||||
now = time.Now()
|
||||
pkg1 = &internal.Package{
|
||||
Path: "path/to/foo/bar",
|
||||
Name: "bar",
|
||||
Synopsis: "This is a package synopsis",
|
||||
}
|
||||
pkg2 = &internal.Package{
|
||||
Path: "path2/to/foo/bar2",
|
||||
Name: "bar2",
|
||||
Synopsis: "This is another package synopsis",
|
||||
}
|
||||
series = &internal.Series{
|
||||
Path: "myseries",
|
||||
}
|
||||
module1 = &internal.Module{
|
||||
Path: "path2/to/foo",
|
||||
Series: series,
|
||||
}
|
||||
module2 = &internal.Module{
|
||||
Path: "path2/to/foo",
|
||||
Series: series,
|
||||
}
|
||||
testVersions = []*internal.Version{
|
||||
&internal.Version{
|
||||
Module: module1,
|
||||
Version: "v1.0.0-alpha.1",
|
||||
License: "licensename",
|
||||
ReadMe: []byte("readme"),
|
||||
CommitTime: now,
|
||||
Packages: []*internal.Package{pkg1},
|
||||
VersionType: internal.VersionTypePrerelease,
|
||||
},
|
||||
&internal.Version{
|
||||
Module: module1,
|
||||
Version: "v1.0.0",
|
||||
License: "licensename",
|
||||
ReadMe: []byte("readme"),
|
||||
CommitTime: now,
|
||||
Packages: []*internal.Package{pkg1},
|
||||
VersionType: internal.VersionTypeRelease,
|
||||
},
|
||||
&internal.Version{
|
||||
Module: module2,
|
||||
Version: "v1.0.0-20190311183353-d8887717615a",
|
||||
License: "licensename",
|
||||
ReadMe: []byte("readme"),
|
||||
CommitTime: now,
|
||||
Packages: []*internal.Package{pkg2},
|
||||
VersionType: internal.VersionTypePseudo,
|
||||
},
|
||||
&internal.Version{
|
||||
Module: module2,
|
||||
Version: "v1.0.1-beta",
|
||||
License: "licensename",
|
||||
ReadMe: []byte("readme"),
|
||||
CommitTime: now,
|
||||
Packages: []*internal.Package{pkg2},
|
||||
VersionType: internal.VersionTypePseudo,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
tc := struct {
|
||||
paths []string
|
||||
versions []*internal.Version
|
||||
wantPkgs []*internal.Package
|
||||
wantReadErr bool
|
||||
}{
|
||||
paths: []string{pkg1.Path, pkg2.Path},
|
||||
versions: testVersions,
|
||||
wantPkgs: []*internal.Package{
|
||||
&internal.Package{
|
||||
Name: pkg1.Name,
|
||||
Path: pkg1.Path,
|
||||
Synopsis: pkg1.Synopsis,
|
||||
Version: &internal.Version{
|
||||
CreatedAt: testVersions[1].CreatedAt,
|
||||
UpdatedAt: testVersions[1].UpdatedAt,
|
||||
Module: &internal.Module{
|
||||
Path: module1.Path,
|
||||
},
|
||||
Version: testVersions[1].Version,
|
||||
Synopsis: testVersions[1].Synopsis,
|
||||
CommitTime: testVersions[1].CommitTime,
|
||||
License: testVersions[1].License,
|
||||
},
|
||||
},
|
||||
&internal.Package{
|
||||
Name: pkg2.Name,
|
||||
Path: pkg2.Path,
|
||||
Synopsis: pkg2.Synopsis,
|
||||
Version: &internal.Version{
|
||||
CreatedAt: testVersions[3].CreatedAt,
|
||||
UpdatedAt: testVersions[3].UpdatedAt,
|
||||
Module: &internal.Module{
|
||||
Path: module1.Path,
|
||||
},
|
||||
Version: testVersions[3].Version,
|
||||
Synopsis: testVersions[3].Synopsis,
|
||||
CommitTime: testVersions[3].CommitTime,
|
||||
License: testVersions[3].License,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, v := range tc.versions {
|
||||
if err := db.InsertVersion(v); err != nil {
|
||||
t.Errorf("db.InsertVersion(%v): %v", v, err)
|
||||
}
|
||||
}
|
||||
|
||||
gotPkgs, err := db.GetLatestPackageForPaths(tc.paths)
|
||||
if (err != nil) != tc.wantReadErr {
|
||||
t.Errorf("db.GetLatestPackageForPaths(%q): %v", tc.paths, err)
|
||||
}
|
||||
|
||||
for i, gotPkg := range gotPkgs {
|
||||
if diff := packagesDiff(gotPkg, tc.wantPkgs[i]); diff != "" {
|
||||
t.Errorf("got %v at index %v, want %v, diff is %v",
|
||||
gotPkg, i, tc.wantPkgs[i], diff)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestPostgress_InsertVersionLogs(t *testing.T) {
|
||||
teardownTestCase, db := SetupCleanDB(t)
|
||||
defer teardownTestCase(t)
|
||||
|
|
Загрузка…
Ссылка в новой задаче