aboutsummaryrefslogtreecommitdiff
path: root/internal/postgres/path.go
diff options
context:
space:
mode:
authorJonathan Amsterdam <jba@google.com>2020-04-27 16:12:09 -0400
committerJonathan Amsterdam <jba@google.com>2020-04-29 20:56:42 +0000
commit0f995de2a3635609f7f95c2efc86e2dab4fcadf0 (patch)
tree9c453c709f35cc11365ae3543e86f97049d4b7f9 /internal/postgres/path.go
parent21584e30257c7768c25dbe8a2dec7279ace4f84b (diff)
downloadgo-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.go49
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