internal: add an interface for internal/postgres.DB
And use that interface to remove the dependency from internal/frontend
to internal/postgres.
The dependency still exists in the test code. That will be taken care
of in another CL.
For #61399
Change-Id: Ic1b3c257e6eb34858cf31b7596251aaff71d3482
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/510417
kokoro-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
diff --git a/internal/frontend/404.go b/internal/frontend/404.go
index 1a062dd..aea7376 100644
--- a/internal/frontend/404.go
+++ b/internal/frontend/404.go
@@ -22,7 +22,6 @@
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/experiment"
"golang.org/x/pkgsite/internal/log"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/pkgsite/internal/version"
)
@@ -47,7 +46,7 @@
ds internal.DataSource, fullPath, modulePath, requestedVersion string) (err error) {
defer derrors.Wrap(&err, "servePathNotFoundPage(w, r, %q, %q)", fullPath, requestedVersion)
- db, ok := ds.(*postgres.DB)
+ db, ok := ds.(internal.PostgresDB)
if !ok {
return datasourceNotSupportedErr()
}
@@ -216,7 +215,7 @@
// previousFetchStatusAndResponse returns the fetch result from a
// previous fetch of the fullPath and requestedVersion.
-func previousFetchStatusAndResponse(ctx context.Context, db *postgres.DB,
+func previousFetchStatusAndResponse(ctx context.Context, db internal.PostgresDB,
fullPath, modulePath, requestedVersion string) (_ *fetchResult, err error) {
defer derrors.Wrap(&err, "previousFetchStatusAndResponse(w, r, %q, %q)", fullPath, requestedVersion)
diff --git a/internal/frontend/fetch.go b/internal/frontend/fetch.go
index 325bfe9..c1050fe 100644
--- a/internal/frontend/fetch.go
+++ b/internal/frontend/fetch.go
@@ -25,7 +25,6 @@
"golang.org/x/pkgsite/internal/experiment"
"golang.org/x/pkgsite/internal/fetch"
"golang.org/x/pkgsite/internal/log"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/proxy"
"golang.org/x/pkgsite/internal/queue"
"golang.org/x/pkgsite/internal/source"
@@ -93,7 +92,7 @@
// result of the request.
func (s *Server) serveFetch(w http.ResponseWriter, r *http.Request, ds internal.DataSource) (err error) {
defer derrors.Wrap(&err, "serveFetch(%q)", r.URL.Path)
- if _, ok := ds.(*postgres.DB); !ok {
+ if _, ok := ds.(internal.PostgresDB); !ok {
// There's no reason for other DataSources to need this codepath.
return datasourceNotSupportedErr()
}
@@ -142,7 +141,7 @@
}
// Generate all possible module paths for the fullPath.
- db := ds.(*postgres.DB)
+ db := ds.(internal.PostgresDB)
modulePaths, err := modulePathsToFetch(ctx, db, fullPath, modulePath)
if err != nil {
var serr *serverError
@@ -171,7 +170,7 @@
// checkPossibleModulePaths will then poll the database for each module path,
// until a result is returned or the request times out. If shouldQueue is false,
// it will return the fetchResult, regardless of what the status is.
-func (s *Server) checkPossibleModulePaths(ctx context.Context, db *postgres.DB,
+func (s *Server) checkPossibleModulePaths(ctx context.Context, db internal.PostgresDB,
fullPath, requestedVersion string, modulePaths []string, shouldQueue bool) []*fetchResult {
var wg sync.WaitGroup
ctx, cancel := context.WithTimeout(ctx, fetchTimeout)
@@ -336,7 +335,7 @@
}
// pollForPath polls the database until a row for fullPath is found.
-func pollForPath(ctx context.Context, db *postgres.DB, pollEvery time.Duration,
+func pollForPath(ctx context.Context, db internal.PostgresDB, pollEvery time.Duration,
fullPath, modulePath, requestedVersion string, taskIDChangeInterval time.Duration) *fetchResult {
fr := &fetchResult{modulePath: modulePath}
defer derrors.Wrap(&fr.err, "pollForRedirectURL(%q, %q, %q)", modulePath, fullPath, requestedVersion)
@@ -370,7 +369,7 @@
// Note that if an error occurs while writing to the version_map table,
// checkForPath will not know. Instead, it will keep running until the request
// times out.
-func checkForPath(ctx context.Context, db *postgres.DB,
+func checkForPath(ctx context.Context, db internal.PostgresDB,
fullPath, modulePath, requestedVersion string, taskIDChangeInterval time.Duration) (fr *fetchResult) {
defer func() {
// Based on
@@ -544,7 +543,7 @@
// worker.FetchAndUpdateState that does not update module_version_states, so that
// we don't have to import internal/worker here. It is not meant to be used
// when running on AppEngine.
-func FetchAndUpdateState(ctx context.Context, modulePath, requestedVersion string, proxyClient *proxy.Client, sourceClient *source.Client, db *postgres.DB) (_ int, err error) {
+func FetchAndUpdateState(ctx context.Context, modulePath, requestedVersion string, proxyClient *proxy.Client, sourceClient *source.Client, db internal.PostgresDB) (_ int, err error) {
defer func() {
if err != nil {
log.Infof(ctx, "FetchAndUpdateState(%q, %q) completed with err: %v. ", modulePath, requestedVersion, err)
diff --git a/internal/frontend/imports.go b/internal/frontend/imports.go
index 947275a..0c21b8e 100644
--- a/internal/frontend/imports.go
+++ b/internal/frontend/imports.go
@@ -11,7 +11,6 @@
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/log"
"golang.org/x/pkgsite/internal/middleware"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/text/message"
)
@@ -95,7 +94,7 @@
// fetchImportedByDetails fetches importers for the package version specified by
// path and version from the database and returns a ImportedByDetails.
func fetchImportedByDetails(ctx context.Context, ds internal.DataSource, pkgPath, modulePath string) (*ImportedByDetails, error) {
- db, ok := ds.(*postgres.DB)
+ db, ok := ds.(internal.PostgresDB)
if !ok {
// The proxydatasource does not support the imported by page.
return nil, datasourceNotSupportedErr()
diff --git a/internal/frontend/redirect.go b/internal/frontend/redirect.go
index aa26648..8ce7235 100644
--- a/internal/frontend/redirect.go
+++ b/internal/frontend/redirect.go
@@ -9,8 +9,8 @@
"net/http"
"strings"
+ "golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/derrors"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/stdlib"
)
@@ -28,7 +28,7 @@
// stdlibPathForShortcut returns a path in the stdlib that shortcut should redirect to,
// or the empty string if there is no such path.
-func stdlibPathForShortcut(ctx context.Context, db *postgres.DB, shortcut string) (path string, err error) {
+func stdlibPathForShortcut(ctx context.Context, db internal.PostgresDB, shortcut string) (path string, err error) {
defer derrors.Wrap(&err, "stdlibPathForShortcut(ctx, %q)", shortcut)
if !stdlib.Contains(shortcut) {
return "", nil
diff --git a/internal/frontend/search.go b/internal/frontend/search.go
index 2ff7833..8ff604a 100644
--- a/internal/frontend/search.go
+++ b/internal/frontend/search.go
@@ -23,7 +23,6 @@
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/log"
"golang.org/x/pkgsite/internal/middleware"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/pkgsite/internal/version"
"golang.org/x/pkgsite/internal/vuln"
@@ -242,7 +241,7 @@
// Pageless search: always start from the beginning.
offset := 0
- dbresults, err := ds.Search(ctx, cq, postgres.SearchOptions{
+ dbresults, err := ds.Search(ctx, cq, internal.SearchOptions{
MaxResults: pageParams.limit,
Offset: offset,
MaxResultCount: maxResultCount,
@@ -287,7 +286,7 @@
return sp, nil
}
-func newSearchResult(r *postgres.SearchResult, searchSymbols bool, pr *message.Printer) *SearchResult {
+func newSearchResult(r *internal.SearchResult, searchSymbols bool, pr *message.Printer) *SearchResult {
// For commands, change the name from "main" to the last component of the import path.
chipText := ""
name := r.Name
@@ -473,7 +472,7 @@
// symbolSynopsis returns the string to be displayed in the code snippet
// section for a symbol search result.
-func symbolSynopsis(r *postgres.SearchResult) string {
+func symbolSynopsis(r *internal.SearchResult) string {
switch r.SymbolKind {
case internal.SymbolKindField:
return fmt.Sprintf(`
@@ -493,7 +492,7 @@
return r.SymbolSynopsis
}
-func packagePaths(heading string, rs []*postgres.SearchResult) *subResult {
+func packagePaths(heading string, rs []*internal.SearchResult) *subResult {
if len(rs) == 0 {
return nil
}
diff --git a/internal/frontend/urlinfo.go b/internal/frontend/urlinfo.go
index 5420dc6..a5dba10 100644
--- a/internal/frontend/urlinfo.go
+++ b/internal/frontend/urlinfo.go
@@ -16,7 +16,6 @@
"golang.org/x/pkgsite/internal/derrors"
"golang.org/x/pkgsite/internal/experiment"
"golang.org/x/pkgsite/internal/log"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/pkgsite/internal/version"
)
@@ -190,7 +189,7 @@
}
func checkExcluded(ctx context.Context, ds internal.DataSource, fullPath string) error {
- db, ok := ds.(*postgres.DB)
+ db, ok := ds.(internal.PostgresDB)
if !ok {
return nil
}
diff --git a/internal/frontend/versions.go b/internal/frontend/versions.go
index 699d04a..773bffd 100644
--- a/internal/frontend/versions.go
+++ b/internal/frontend/versions.go
@@ -15,7 +15,6 @@
"golang.org/x/mod/semver"
"golang.org/x/pkgsite/internal"
"golang.org/x/pkgsite/internal/log"
- "golang.org/x/pkgsite/internal/postgres"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/pkgsite/internal/version"
"golang.org/x/pkgsite/internal/vuln"
@@ -86,7 +85,7 @@
}
func fetchVersionsDetails(ctx context.Context, ds internal.DataSource, um *internal.UnitMeta, vc *vuln.Client) (*VersionsDetails, error) {
- db, ok := ds.(*postgres.DB)
+ db, ok := ds.(internal.PostgresDB)
if !ok {
// The proxydatasource does not support the imported by page.
return nil, datasourceNotSupportedErr()
diff --git a/internal/interfaces.go b/internal/interfaces.go
new file mode 100644
index 0000000..b2331d5
--- /dev/null
+++ b/internal/interfaces.go
@@ -0,0 +1,27 @@
+// Copyright 2023 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 internal
+
+import "context"
+
+// PostgresDB provides an interface satisfied by *(internal/postgres.DB) so that
+// packages in pkgsite can use the database if it exists without needing a
+// dependency on the database driver packages.
+type PostgresDB interface {
+ DataSource
+ IsPostgresDB()
+
+ IsExcluded(ctx context.Context, path string) (_ bool, err error)
+ GetImportedBy(ctx context.Context, pkgPath, modulePath string, limit int) (paths []string, err error)
+ GetImportedByCount(ctx context.Context, pkgPath, modulePath string) (_ int, err error)
+ GetLatestMajorPathForV1Path(ctx context.Context, v1path string) (_ string, _ int, err error)
+ GetStdlibPathsWithSuffix(ctx context.Context, suffix string) (paths []string, err error)
+ GetSymbolHistory(ctx context.Context, packagePath, modulePath string) (_ *SymbolHistory, err error)
+ GetVersionMap(ctx context.Context, modulePath, requestedVersion string) (_ *VersionMap, err error)
+ GetVersionMaps(ctx context.Context, paths []string, requestedVersion string) (_ []*VersionMap, err error)
+ GetVersionsForPath(ctx context.Context, path string) (_ []*ModuleInfo, err error)
+ InsertModule(ctx context.Context, m *Module, lmv *LatestModuleVersions) (isLatest bool, err error)
+ UpsertVersionMap(ctx context.Context, vm *VersionMap) (err error)
+}
diff --git a/internal/postgres/postgres.go b/internal/postgres/postgres.go
index d56f08c..45de904 100644
--- a/internal/postgres/postgres.go
+++ b/internal/postgres/postgres.go
@@ -29,6 +29,11 @@
return newdb(db, false)
}
+// Used to check that a DataSource is a PostgresDB without doing a
+// direct type assertion on *DB.
+func (*DB) IsPostgresDB() {
+}
+
// NewBypassingLicenseCheck returns a new postgres DB that bypasses license
// checks. That means all data will be inserted and returned for
// non-redistributable modules, packages and directories.