diff options
| author | Jonathan Amsterdam <jba@google.com> | 2020-04-27 16:12:09 -0400 |
|---|---|---|
| committer | Jonathan Amsterdam <jba@google.com> | 2020-04-29 20:56:42 +0000 |
| commit | 0f995de2a3635609f7f95c2efc86e2dab4fcadf0 (patch) | |
| tree | 9c453c709f35cc11365ae3543e86f97049d4b7f9 /internal/postgres/path.go | |
| parent | 21584e30257c7768c25dbe8a2dec7279ace4f84b (diff) | |
| download | go-x-pkgsite-0f995de2a3635609f7f95c2efc86e2dab4fcadf0.tar.xz | |
internal/postgres: support for getting path info
Add GetPathInfo, a function that gets information about a path. The
main handler would call either GetPathInfo(path, "unknown", "latest")
if the incoming URL path had no "@", or GetPathInfo(path, "unknown",
version) if the incoming path looked like "foo@v".
Based on the returned path (or absence of one), it would decide whether
to call GetDirectory, GetPackage or GetModule.
Change-Id: Ifc09202d8ec110960e2c3bbaf04b79fc7a7c72df
Reviewed-on: https://team-review.git.corp.google.com/c/golang/discovery/+/728098
Reviewed-by: Julie Qiu <julieqiu@google.com>
Diffstat (limited to 'internal/postgres/path.go')
| -rw-r--r-- | internal/postgres/path.go | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/internal/postgres/path.go b/internal/postgres/path.go index 5a4cd238..b96fa87a 100644 --- a/internal/postgres/path.go +++ b/internal/postgres/path.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Go Authors. All rights reserved. +// Copyright 2020 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -8,11 +8,58 @@ import ( "context" "database/sql" "fmt" + "strings" "github.com/lib/pq" + "golang.org/x/pkgsite/internal" "golang.org/x/pkgsite/internal/derrors" ) +// GetPathInfo returns information about the "best" entity (module, path or directory) with +// the given path. The module and version arguments provide additional constraints. +// If the module is unknown, pass internal.UnknownModulePath; if the version is unknown, pass +// internal.LatestVersion. +// +// The rules for picking the best are: +// 1. Match the module path and or version, if they are provided; +// 2. Prefer newer module versions to older, and release to pre-release; +// 3. In the unlikely event of two paths at the same version, pick the longer module path. +func (db *DB) GetPathInfo(ctx context.Context, path, inModulePath, inVersion string) (outModulePath, outVersion string, isPackage bool, err error) { + defer derrors.Wrap(&err, "DB.GetPathInfo(ctx, %q, %q, %q)", path, inModulePath, inVersion) + + var constraints []string + args := []interface{}{path} + if inModulePath != internal.UnknownModulePath { + constraints = append(constraints, fmt.Sprintf("AND m.module_path = $%d", len(args)+1)) + args = append(args, inModulePath) + } + if inVersion != internal.LatestVersion { + constraints = append(constraints, fmt.Sprintf("AND m.version = $%d", len(args)+1)) + args = append(args, inVersion) + } + query := fmt.Sprintf(` + SELECT m.module_path, m.version, p.name != '' + FROM paths p + INNER JOIN modules m ON (p.module_id = m.id) + WHERE p.path = $1 + %s + ORDER BY + m.version_type = 'release' DESC, + m.sort_version DESC, + m.module_path DESC + LIMIT 1 + `, strings.Join(constraints, " ")) + err = db.db.QueryRow(ctx, query, args...).Scan(&outModulePath, &outVersion, &isPackage) + switch err { + case sql.ErrNoRows: + return "", "", false, derrors.NotFound + case nil: + return outModulePath, outVersion, isPackage, nil + default: + return "", "", false, err + } +} + type dbPath struct { id int64 path string |
