internal/postgres: move unit queries to unit.go
GetUnitMeta and getPathsInModule are moved to unit.go.
path.go is renamed to stdlib.go
Pure code in motion.
Change-Id: If34cd8f3a88104637085994d846ed3ca823c639f
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/271098
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
diff --git a/internal/postgres/path.go b/internal/postgres/path.go
deleted file mode 100644
index 2a5e9d5..0000000
--- a/internal/postgres/path.go
+++ /dev/null
@@ -1,213 +0,0 @@
-// 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.
-
-package postgres
-
-import (
- "context"
- "database/sql"
- "fmt"
- "strings"
-
- "github.com/lib/pq"
- "golang.org/x/pkgsite/internal"
- "golang.org/x/pkgsite/internal/derrors"
- "golang.org/x/pkgsite/internal/middleware"
- "golang.org/x/pkgsite/internal/stdlib"
-)
-
-// orderByLatest orders paths according to the go command.
-// Versions are ordered by:
-// (1) release (non-incompatible)
-// (2) prerelease (non-incompatible)
-// (3) release, incompatible
-// (4) prerelease, incompatible
-// (5) pseudo
-// They are then sorted based on semver, then decreasing module path length (so
-// that nested modules are preferred).
-const orderByLatest = `
- ORDER BY
- CASE
- WHEN m.version_type = 'release' AND NOT m.incompatible THEN 1
- WHEN m.version_type = 'prerelease' AND NOT m.incompatible THEN 2
- WHEN m.version_type = 'release' THEN 3
- WHEN m.version_type = 'prerelease' THEN 4
- ELSE 5
- END,
- m.sort_version DESC,
- m.module_path DESC`
-
-// GetUnitMeta 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) GetUnitMeta(ctx context.Context, path, requestedModulePath, requestedVersion string) (_ *internal.UnitMeta, err error) {
- defer derrors.Wrap(&err, "DB.GetUnitMeta(ctx, %q, %q, %q)", path, requestedModulePath, requestedVersion)
- defer middleware.ElapsedStat(ctx, "GetUnitMeta")()
-
- var (
- constraints []string
- joinStmt string
- )
- args := []interface{}{path}
- if requestedModulePath != internal.UnknownModulePath {
- constraints = append(constraints, fmt.Sprintf("AND m.module_path = $%d", len(args)+1))
- args = append(args, requestedModulePath)
- }
- switch requestedVersion {
- case internal.LatestVersion:
- case internal.MasterVersion:
- joinStmt = "INNER JOIN version_map vm ON (vm.module_id = m.id)"
- constraints = append(constraints, "AND vm.requested_version = 'master'")
- default:
- constraints = append(constraints, fmt.Sprintf("AND m.version = $%d", len(args)+1))
- args = append(args, requestedVersion)
- }
-
- var (
- licenseTypes []string
- licensePaths []string
- um = internal.UnitMeta{Path: path}
- )
- query := fmt.Sprintf(`
- SELECT
- m.module_path,
- m.version,
- m.commit_time,
- m.source_info,
- p.name,
- p.redistributable,
- p.license_types,
- p.license_paths
- FROM units p
- INNER JOIN modules m ON (p.module_id = m.id)
- %s
- WHERE p.path = $1
- %s
- %s
- LIMIT 1
- `, joinStmt, strings.Join(constraints, " "), orderByLatest)
- err = db.db.QueryRow(ctx, query, args...).Scan(
- &um.ModulePath,
- &um.Version,
- &um.CommitTime,
- jsonbScanner{&um.SourceInfo},
- &um.Name,
- &um.IsRedistributable,
- pq.Array(&licenseTypes),
- pq.Array(&licensePaths))
- switch err {
- case sql.ErrNoRows:
- return nil, derrors.NotFound
- case nil:
- lics, err := zipLicenseMetadata(licenseTypes, licensePaths)
- if err != nil {
- return nil, err
- }
-
- if db.bypassLicenseCheck {
- um.IsRedistributable = true
- }
-
- um.Licenses = lics
- return &um, nil
- default:
- return nil, err
- }
-}
-
-type dbPath struct {
- id int64
- path string
- moduleID int64
- v1Path string
- name string
- licenseTypes []string
- licensePaths []string
- redistributable bool
-}
-
-func (db *DB) getPathsInModule(ctx context.Context, modulePath, resolvedVersion string) (_ []*dbPath, err error) {
- defer derrors.Wrap(&err, "DB.getPathsInModule(ctx, %q, %q)", modulePath, resolvedVersion)
- query := `
- SELECT
- p.id,
- p.path,
- p.module_id,
- p.v1_path,
- p.name,
- p.license_types,
- p.license_paths,
- p.redistributable
- FROM
- units p
- INNER JOIN
- modules m
- ON
- p.module_id = m.id
- WHERE
- m.module_path = $1
- AND m.version = $2
- ORDER BY path;`
-
- var paths []*dbPath
- collect := func(rows *sql.Rows) error {
- var p dbPath
- if err := rows.Scan(&p.id, &p.path, &p.moduleID, &p.v1Path, &p.name, pq.Array(&p.licenseTypes),
- pq.Array(&p.licensePaths), &p.redistributable); err != nil {
- return fmt.Errorf("row.Scan(): %v", err)
- }
- paths = append(paths, &p)
- return nil
- }
- if err := db.db.RunQuery(ctx, query, collect, modulePath, resolvedVersion); err != nil {
- return nil, err
- }
- return paths, nil
-}
-
-// GetStdlibPathsWithSuffix returns information about all paths in the latest version of the standard
-// library whose last component is suffix. A path that exactly match suffix is not included;
-// the path must end with "/" + suffix.
-//
-// We are only interested in actual standard library packages: not commands, which we happen to include
-// in the stdlib module, and not directories (paths that do not contain a package).
-func (db *DB) GetStdlibPathsWithSuffix(ctx context.Context, suffix string) (paths []string, err error) {
- defer derrors.Wrap(&err, "DB.GetStdlibPaths(ctx, %q)", suffix)
-
- q := `
- SELECT path
- FROM units
- WHERE module_id = (
- -- latest release version of stdlib
- SELECT id
- FROM modules
- WHERE module_path = $1
- ORDER BY
- version_type = 'release' DESC,
- sort_version DESC
- LIMIT 1)
- AND name != ''
- AND path NOT LIKE 'cmd/%'
- AND path LIKE '%/' || $2
- ORDER BY path
- `
- err = db.db.RunQuery(ctx, q, func(rows *sql.Rows) error {
- var p string
- if err := rows.Scan(&p); err != nil {
- return err
- }
- paths = append(paths, p)
- return nil
- }, stdlib.ModulePath, suffix)
- if err != nil {
- return nil, err
- }
- return paths, nil
-}
diff --git a/internal/postgres/stdlib.go b/internal/postgres/stdlib.go
new file mode 100644
index 0000000..553e8bf
--- /dev/null
+++ b/internal/postgres/stdlib.go
@@ -0,0 +1,53 @@
+// 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.
+
+package postgres
+
+import (
+ "context"
+ "database/sql"
+
+ "golang.org/x/pkgsite/internal/derrors"
+ "golang.org/x/pkgsite/internal/stdlib"
+)
+
+// GetStdlibPathsWithSuffix returns information about all paths in the latest version of the standard
+// library whose last component is suffix. A path that exactly match suffix is not included;
+// the path must end with "/" + suffix.
+//
+// We are only interested in actual standard library packages: not commands, which we happen to include
+// in the stdlib module, and not directories (paths that do not contain a package).
+func (db *DB) GetStdlibPathsWithSuffix(ctx context.Context, suffix string) (paths []string, err error) {
+ defer derrors.Wrap(&err, "DB.GetStdlibPaths(ctx, %q)", suffix)
+
+ q := `
+ SELECT path
+ FROM units
+ WHERE module_id = (
+ -- latest release version of stdlib
+ SELECT id
+ FROM modules
+ WHERE module_path = $1
+ ORDER BY
+ version_type = 'release' DESC,
+ sort_version DESC
+ LIMIT 1)
+ AND name != ''
+ AND path NOT LIKE 'cmd/%'
+ AND path LIKE '%/' || $2
+ ORDER BY path
+ `
+ err = db.db.RunQuery(ctx, q, func(rows *sql.Rows) error {
+ var p string
+ if err := rows.Scan(&p); err != nil {
+ return err
+ }
+ paths = append(paths, p)
+ return nil
+ }, stdlib.ModulePath, suffix)
+ if err != nil {
+ return nil, err
+ }
+ return paths, nil
+}
diff --git a/internal/postgres/unit.go b/internal/postgres/unit.go
index d8a0bed..cee8d51 100644
--- a/internal/postgres/unit.go
+++ b/internal/postgres/unit.go
@@ -20,6 +20,111 @@
"golang.org/x/pkgsite/internal/stdlib"
)
+// GetUnitMeta 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) GetUnitMeta(ctx context.Context, path, requestedModulePath, requestedVersion string) (_ *internal.UnitMeta, err error) {
+ defer derrors.Wrap(&err, "DB.GetUnitMeta(ctx, %q, %q, %q)", path, requestedModulePath, requestedVersion)
+ defer middleware.ElapsedStat(ctx, "GetUnitMeta")()
+
+ var (
+ constraints []string
+ joinStmt string
+ )
+ args := []interface{}{path}
+ if requestedModulePath != internal.UnknownModulePath {
+ constraints = append(constraints, fmt.Sprintf("AND m.module_path = $%d", len(args)+1))
+ args = append(args, requestedModulePath)
+ }
+ switch requestedVersion {
+ case internal.LatestVersion:
+ case internal.MasterVersion:
+ joinStmt = "INNER JOIN version_map vm ON (vm.module_id = m.id)"
+ constraints = append(constraints, "AND vm.requested_version = 'master'")
+ default:
+ constraints = append(constraints, fmt.Sprintf("AND m.version = $%d", len(args)+1))
+ args = append(args, requestedVersion)
+ }
+
+ var (
+ licenseTypes []string
+ licensePaths []string
+ um = internal.UnitMeta{Path: path}
+ )
+ query := fmt.Sprintf(`
+ SELECT
+ m.module_path,
+ m.version,
+ m.commit_time,
+ m.source_info,
+ p.name,
+ p.redistributable,
+ p.license_types,
+ p.license_paths
+ FROM units p
+ INNER JOIN modules m ON (p.module_id = m.id)
+ %s
+ WHERE p.path = $1
+ %s
+ %s
+ LIMIT 1
+ `, joinStmt, strings.Join(constraints, " "), orderByLatest)
+ err = db.db.QueryRow(ctx, query, args...).Scan(
+ &um.ModulePath,
+ &um.Version,
+ &um.CommitTime,
+ jsonbScanner{&um.SourceInfo},
+ &um.Name,
+ &um.IsRedistributable,
+ pq.Array(&licenseTypes),
+ pq.Array(&licensePaths))
+ switch err {
+ case sql.ErrNoRows:
+ return nil, derrors.NotFound
+ case nil:
+ lics, err := zipLicenseMetadata(licenseTypes, licensePaths)
+ if err != nil {
+ return nil, err
+ }
+
+ if db.bypassLicenseCheck {
+ um.IsRedistributable = true
+ }
+
+ um.Licenses = lics
+ return &um, nil
+ default:
+ return nil, err
+ }
+}
+
+// orderByLatest orders paths according to the go command.
+// Versions are ordered by:
+// (1) release (non-incompatible)
+// (2) prerelease (non-incompatible)
+// (3) release, incompatible
+// (4) prerelease, incompatible
+// (5) pseudo
+// They are then sorted based on semver, then decreasing module path length (so
+// that nested modules are preferred).
+const orderByLatest = `
+ ORDER BY
+ CASE
+ WHEN m.version_type = 'release' AND NOT m.incompatible THEN 1
+ WHEN m.version_type = 'prerelease' AND NOT m.incompatible THEN 2
+ WHEN m.version_type = 'release' THEN 3
+ WHEN m.version_type = 'prerelease' THEN 4
+ ELSE 5
+ END,
+ m.sort_version DESC,
+ m.module_path DESC`
+
// GetUnit returns a unit from the database, along with all of the
// data associated with that unit.
// TODO(golang/go#39629): remove pID.
@@ -347,3 +452,53 @@
u.UnitMeta = *um
return &u, nil
}
+
+type dbPath struct {
+ id int64
+ path string
+ moduleID int64
+ v1Path string
+ name string
+ licenseTypes []string
+ licensePaths []string
+ redistributable bool
+}
+
+func (db *DB) getPathsInModule(ctx context.Context, modulePath, resolvedVersion string) (_ []*dbPath, err error) {
+ defer derrors.Wrap(&err, "DB.getPathsInModule(ctx, %q, %q)", modulePath, resolvedVersion)
+ query := `
+ SELECT
+ p.id,
+ p.path,
+ p.module_id,
+ p.v1_path,
+ p.name,
+ p.license_types,
+ p.license_paths,
+ p.redistributable
+ FROM
+ units p
+ INNER JOIN
+ modules m
+ ON
+ p.module_id = m.id
+ WHERE
+ m.module_path = $1
+ AND m.version = $2
+ ORDER BY path;`
+
+ var paths []*dbPath
+ collect := func(rows *sql.Rows) error {
+ var p dbPath
+ if err := rows.Scan(&p.id, &p.path, &p.moduleID, &p.v1Path, &p.name, pq.Array(&p.licenseTypes),
+ pq.Array(&p.licensePaths), &p.redistributable); err != nil {
+ return fmt.Errorf("row.Scan(): %v", err)
+ }
+ paths = append(paths, &p)
+ return nil
+ }
+ if err := db.db.RunQuery(ctx, query, collect, modulePath, resolvedVersion); err != nil {
+ return nil, err
+ }
+ return paths, nil
+}