aboutsummaryrefslogtreecommitdiff
path: root/internal/postgres/postgres.go
diff options
context:
space:
mode:
authorJulie Qiu <julie@golang.org>2019-04-02 17:22:51 -0400
committerJulie Qiu <julie@golang.org>2020-03-27 16:46:34 -0400
commitb3932ac94fc4e80cbd903aa5404e9c895fdb8430 (patch)
tree2fa9bd982bc81a115eaf26965fd785fdb8f3fd90 /internal/postgres/postgres.go
parentd61efba1e2cfb45c9b97d0183ef5815310feb03a (diff)
downloadgo-x-pkgsite-b3932ac94fc4e80cbd903aa5404e9c895fdb8430.tar.xz
internal/postgres: implement InsertDocuments and Search
InsertDocuments inserts the packages for a given version into the documents table, and creates tsvector tokens to allow for searching package name, package path, synopsis tokens, and readme tokens. Search fetches packages that match a given set of terms, and returns them in order of rank. Rank is based on relevance and the number of dependents. Change-Id: I60e8b690955adb66306e326238e426cf77527f82 Reviewed-on: https://team-review.git.corp.google.com/c/golang/discovery/+/443363 Reviewed-by: Andrew Bonventre <andybons@google.com>
Diffstat (limited to 'internal/postgres/postgres.go')
-rw-r--r--internal/postgres/postgres.go78
1 files changed, 57 insertions, 21 deletions
diff --git a/internal/postgres/postgres.go b/internal/postgres/postgres.go
index 39b0e28e..72c3c76e 100644
--- a/internal/postgres/postgres.go
+++ b/internal/postgres/postgres.go
@@ -55,6 +55,22 @@ func (db *DB) Transact(txFunc func(*sql.Tx) error) (err error) {
return txFunc(tx)
}
+// prepareAndExec prepares a query statement and executes it insde the provided
+// transaction.
+func prepareAndExec(tx *sql.Tx, query string, stmtFunc func(*sql.Stmt) error) (err error) {
+ stmt, err := tx.Prepare(query)
+ if err != nil {
+ return fmt.Errorf("tx.Prepare(%q): %v", query, err)
+ }
+
+ defer func() {
+ if err = stmt.Close(); err != nil {
+ err = fmt.Errorf("stmt.Close: %v", err)
+ }
+ }()
+ return stmtFunc(stmt)
+}
+
// LatestProxyIndexUpdate reports the last time the Proxy Index Cron
// successfully fetched data from the Module Proxy Index.
func (db *DB) LatestProxyIndexUpdate() (time.Time, error) {
@@ -458,27 +474,8 @@ func padPrerelease(p string) (string, error) {
// so all number fields in the prerelease column have 20 characters. If the
// version is malformed then insertion will fail.
func (db *DB) InsertVersion(version *internal.Version) error {
- if version == nil || !semver.IsValid(version.Version) || version.Module == nil {
- return status.Errorf(codes.InvalidArgument, "postgres: cannot insert nil or invalid version")
- }
-
- if err := module.CheckPath(version.Module.Path); err != nil {
- return status.Errorf(codes.InvalidArgument, "postgres: cannot insert version with invalid module path: %v", err)
- }
-
- if version.Module == nil || version.Module.Path == "" || version.Version == "" || version.CommitTime.IsZero() {
- var errReasons []string
- if version.Module == nil || version.Module.Path == "" {
- errReasons = append(errReasons, "no module path")
- }
- if version.Version == "" {
- errReasons = append(errReasons, "no specified version")
- }
- if version.CommitTime.IsZero() {
- errReasons = append(errReasons, "empty commit time")
- }
- return status.Errorf(codes.InvalidArgument,
- fmt.Sprintf("postgres: cannot insert version %v: %s", version, strings.Join(errReasons, ", ")))
+ if err := validateVersion(version); err != nil {
+ return status.Errorf(codes.InvalidArgument, fmt.Sprintf("validateVersion(%+v): %v", version, err))
}
return db.Transact(func(tx *sql.Tx) error {
@@ -624,3 +621,42 @@ func (db *DB) GetLatestPackageForPaths(paths []string) ([]*internal.Package, err
return packages, nil
}
+
+// validateVersion checks that fields needed to insert a version into the
+// database are present. Otherwise, it returns an error listing the reasons the
+// version cannot be inserted.
+func validateVersion(version *internal.Version) error {
+ if version == nil {
+ return fmt.Errorf("nil version")
+ }
+
+ var errReasons []string
+
+ if version.Version == "" {
+ errReasons = append(errReasons, "no specified version")
+ } else if !semver.IsValid(version.Version) {
+ errReasons = append(errReasons, "invalid version")
+ }
+
+ if version.Module == nil || version.Module.Path == "" {
+ errReasons = append(errReasons, "no module path")
+ } else if err := module.CheckPath(version.Module.Path); err != nil {
+ errReasons = append(errReasons, "invalid module path")
+ } else if version.Module.Series == nil || version.Module.Series.Path == "" {
+ errReasons = append(errReasons, "no series path")
+ }
+
+ if version.CommitTime.IsZero() {
+ errReasons = append(errReasons, "empty commit time")
+ }
+
+ if version.Packages == nil || len(version.Packages) == 0 {
+ errReasons = append(errReasons, "no packages")
+ }
+
+ if len(errReasons) == 0 {
+ return nil
+ }
+
+ return fmt.Errorf("cannot insert version %v: %s", version, strings.Join(errReasons, ", "))
+}