Source File
insert_module.go
Belonging Package
golang.org/x/pkgsite/internal/postgres
package postgres
import (
)
func ( *DB) ( context.Context, *internal.Module, *internal.LatestModuleVersions) ( bool, error) {
defer func() {
if == nil {
derrors.WrapStack(&, "DB.InsertModule(ctx, nil)")
return
}
derrors.WrapStack(&, "DB.InsertModule(ctx, Module(%q, %q))", .ModulePath, .Version)
}()
if := validateModule(); != nil {
return false,
if := .comparePaths(, ); != nil {
return false,
}
.RemoveNonRedistributableData()
}
return .saveModule(, , )
}
if := .compareLicenses(, , .Licenses); != nil {
return
}
if := insertLicenses(, , , ); != nil {
return
}
if := .insertUnits(, , , , ); != nil {
return
}
if := lock(, , .ModulePath); != nil {
return
}
, := getLatestGoodVersion(, , .ModulePath, )
if != nil {
return
if := updateLatestGoodVersion(, , .ModulePath, ); != nil {
return
}
= .Version ==
if ! {
return nil
if := insertImportsUnique(, , ); != nil {
return
}
, := isAlternativeModulePath(, , .ModulePath)
if != nil {
return
}
if {
log.Infof(, "%s@%s: not inserting into search documents", .ModulePath, .Version)
return nil
return upsertSearchDocuments(, , )
})
if != nil {
return false,
}
return , nil
}
return false, nil
case nil:
return == derrors.ToStatus(derrors.AlternativeModule), nil
default:
return false,
}
}
func ( context.Context, *database.DB, *internal.Module) ( int, error) {
, := trace.StartSpan(, "insertModule")
defer .End()
defer derrors.WrapStack(&, "insertModule(ctx, %q, %q)", .ModulePath, .Version)
, := json.Marshal(.SourceInfo)
if != nil {
return 0,
}
, := version.ParseType(.Version)
if != nil {
return 0,
}
var int
= .QueryRow(,
`INSERT INTO modules(
module_path,
version,
commit_time,
sort_version,
version_type,
series_path,
source_info,
redistributable,
has_go_mod,
incompatible)
VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)
ON CONFLICT
(module_path, version)
DO UPDATE SET
source_info=excluded.source_info,
redistributable=excluded.redistributable
RETURNING id`,
.ModulePath,
.Version,
.CommitTime,
version.ForSorting(.Version),
,
.SeriesPath(),
,
.IsRedistributable,
.HasGoMod,
version.IsIncompatible(.Version),
).Scan(&)
if != nil {
return 0,
}
return , nil
}
func ( context.Context, *database.DB, *internal.Module, int) ( error) {
, := trace.StartSpan(, "insertLicenses")
defer .End()
defer derrors.WrapStack(&, "insertLicenses(ctx, %q, %q)", .ModulePath, .Version)
var []interface{}
for , := range .Licenses {
var []byte
if .Coverage.Percent == 0 && .Coverage.Match == nil {
, = json.Marshal(.OldCoverage)
if != nil {
return fmt.Errorf("marshalling %+v: %v", .OldCoverage, )
}
} else {
, = json.Marshal(.Coverage)
if != nil {
return fmt.Errorf("marshalling %+v: %v", .Coverage, )
}
}
= append(, .FilePath,
makeValidUnicode(string(.Contents)), pq.Array(.Types), ,
)
}
if len() > 0 {
:= []string{
"file_path",
"contents",
"types",
"coverage",
"module_id",
}
return .BulkUpsert(, "licenses", , ,
[]string{"module_id", "file_path"})
}
return nil
}
if , := .Exec(,
`DELETE FROM imports_unique WHERE from_module_path = $1`,
.ModulePath); != nil {
return
}
var []interface{}
for , := range .Units {
for , := range .Imports {
= append(, .Path, .ModulePath, )
}
}
if len() == 0 {
return nil
}
:= []string{"from_path", "from_module_path", "to_path"}
return .BulkUpsert(, "imports_unique", , , )
}
sort.Slice(.Units, func(, int) bool {
return .Units[].Path < .Units[].Path
})
for , := range .Units {
sort.Strings(.Imports)
}
var (
[]string
[]interface{}
= map[string]*internal.Readme{}
= map[string][]*internal.Documentation{}
= map[string][]string{}
= map[int]string{}
)
for , := range .Units {
var , []string
for , := range .Licenses {
= append(, "")
= append(, .FilePath)
} else {
for , := range .Types {
= append(, )
= append(, .FilePath)
}
}
}
:= internal.V1Path(.Path, .ModulePath)
, := [.Path]
if ! {
return fmt.Errorf("no entry in paths table for %q; should be impossible", .Path)
}
[] = .Path
= append(,
,
,
[],
.Name,
pq.Array(),
pq.Array(),
.IsRedistributable,
)
if .Readme != nil {
[.Path] = .Readme
}
for , := range .Documentation {
if .Source == nil {
return fmt.Errorf("insertUnits: unit %q missing source files for %q, %q", .Path, .GOOS, .GOARCH)
}
}
[.Path] = .Documentation
if len(.Imports) > 0 {
[.Path] = .Imports
}
= append(, .Path)
}
, := insertUnits(, , )
if != nil {
return
}
:= map[string]int{}
for , := range {
[[]] =
}
if := insertReadmes(, , , , ); != nil {
return
}
if := insertDocs(, , , , ); != nil {
return
}
if := insertImports(, , , , ); != nil {
return
}
, := getDocIDsForPath(, , , )
if != nil {
return
, := version.ParseType(.Version)
if != nil {
return
}
if == version.TypeRelease {
return insertSymbols(, , .ModulePath, .Version, , )
}
return nil
}
:= map[string]bool{}
for , := range .Units {
[.Path] = true
[internal.V1Path(.Path, .ModulePath)] = true
[internal.SeriesPathForModule(.ModulePath)] = true
}
var []string
for := range {
= append(, )
}
return upsertPaths(, , )
}
func ( context.Context, *database.DB, []interface{}) ( map[int]int, error) {
defer derrors.WrapAndReport(&, "insertUnits")
:= map[[2]interface{}]bool{}
for := 0; < len(); += len() {
:= [2]interface{}{[], [+1]}
if [] {
log.Errorf(, "insertUnits: %v occurs twice", )
} else {
[] = true
}
}
= map[int]int{}
if := .BulkUpsertReturning(, "units", , ,
, , func( *sql.Rows) error {
var , int
if := .Scan(&, &); != nil {
return
}
[] =
return nil
}); != nil {
log.Errorf(, "got error doing bulk upsert to units (see below); logging path_id, module_id for golang.org/issue/43899")
for := 0; < len(); += len() {
log.Errorf(, "%v, %v", [], [+1])
}
return nil,
}
return , nil
}
func ( context.Context, *database.DB,
[]string,
map[string]int,
map[string][]*internal.Documentation) ( error) {
defer derrors.WrapStack(&, "insertDocs(%d paths)", len())
:= func() chan database.RowItem {
:= make(chan database.RowItem)
go func() {
for , := range {
:= []
for , := range [] {
if .GOOS == "" || .GOARCH == "" {
<- database.RowItem{Err: errors.New("empty GOOS or GOARCH")}
}
<- database.RowItem{Values: []interface{}{, .GOOS, .GOARCH, .Synopsis, .Source}}
}
}
close()
}()
return
}
:= []string{"unit_id", "goos", "goarch"}
:= append(, "synopsis", "source")
return .CopyUpsert(, "documentation",
, database.CopyFromChan(()), , "id")
}
func ( context.Context, *database.DB,
map[string]int,
map[string][]*internal.Documentation) ( map[string]map[int]*internal.Documentation, error) {
defer derrors.WrapStack(&, "getDocIDsForPath")
:= map[string]map[int]*internal.Documentation{}
:= map[int]string{}
:= func( *sql.Rows) error {
var (
, int
, string
)
if := .Scan(&, &, &, &); != nil {
return
}
:= []
if , := []; ! {
[] = map[int]*internal.Documentation{}
}
for , := range [] {
if .GOOS == && .GOARCH == {
[][] =
}
}
return nil
}
var []int
for := range {
[[]] =
= append(, [])
}
:= `SELECT id, unit_id, goos, goarch FROM documentation WHERE unit_id = ANY($1)`
if := .RunQuery(, , , pq.Array()); != nil {
return nil,
}
return , nil
}
func ( context.Context, *database.DB,
[]string,
map[string]int,
map[string][]string) ( error) {
defer derrors.WrapStack(&, "insertImports")
var []interface{}
for , := range {
, := []
if ! {
continue
}
:= []
for , := range {
= append(, , )
}
}
:= []string{"unit_id", "to_path"}
return .BulkUpsert(, "package_imports", , , )
}
func ( context.Context, *database.DB,
[]string,
map[string]int,
map[string]*internal.Readme) ( error) {
defer derrors.WrapStack(&, "insertReadmes")
var []interface{}
for , := range {
, := []
if ! {
continue
}
:= makeValidUnicode(.Contents)
if len() == 0 {
continue
}
:= []
= append(, , .Filepath, )
}
:= []string{"unit_id", "file_path", "contents"}
return .BulkUpsert(, "readmes", , , []string{"unit_id"})
}
var int
switch := .QueryRow(, `
SELECT 1
FROM search_documents
WHERE module_path = $1
AND version = $2
`, , .GoodVersion).Scan(&); {
case sql.ErrNoRows:
break
case nil:
log.Debugf(, "ReInsertLatestVersion(%q): good version %s found in search_documents; doing nothing",
, .GoodVersion)
return nil
default:
return
}
, := isAlternativeModulePath(, , )
if != nil {
return
}
if {
log.Debugf(, "ReInsertLatestVersion(%q): alternative module path; doing nothing", )
return nil
}
, := getPackagesInUnit(, , , , .GoodVersion, -1, .bypassLicenseCheck)
if != nil {
return
, := getModuleReadme(, , , .GoodVersion)
if != nil && !errors.Is(, derrors.NotFound) {
return
}
for , := range {
if isInternalPackage(.Path) {
continue
}
:= UpsertSearchDocumentArgs{
PackagePath: .Path,
ModulePath: ,
Version: .GoodVersion,
Synopsis: .Synopsis,
}
if .Path == && != nil {
.ReadmeFilePath = .Filepath
.ReadmeContents = .Contents
}
if := UpsertSearchDocument(, , ); != nil {
return
}
}
if , := .Exec(, `
INSERT INTO imports_unique (from_path, from_module_path, to_path)
SELECT p.path, m.module_path, i.to_path
FROM units u
INNER JOIN package_imports i ON (u.id = i.unit_id)
INNER JOIN paths p ON (p.id = u.path_id)
INNER JOIN modules m ON (m.id=u.module_id)
WHERE m.module_path = $1 and m.version = $2
`, , .GoodVersion); != nil {
return
}
log.Debugf(, "ReInsertLatestVersion(%q): re-inserted at latest good version %s", , .GoodVersion)
return nil
})
}
:= fnv.New64()
io.WriteString(, ) // Writing to a hash.Hash never returns an error.
:= int64(.Sum64())
if !database.QueryLoggingDisabled {
log.Debugf(, "locking %s (%d) ...", , )
func ( *internal.Module) ( error) {
defer func() {
if != nil {
= fmt.Errorf("%v: %w", , derrors.DBModuleInsertInvalid)
if != nil {
derrors.WrapStack(&, "validateModule(%q, %q)", .ModulePath, .Version)
}
}
}()
if == nil {
return fmt.Errorf("nil module")
}
var []string
if .Version == "" {
= append(, "no specified version")
}
if .ModulePath == "" {
= append(, "no module path")
}
if .ModulePath != stdlib.ModulePath {
if := module.CheckPath(.ModulePath); != nil {
= append(, fmt.Sprintf("invalid module path (%s)", ))
}
if !semver.IsValid(.Version) {
= append(, "invalid version")
}
}
if len(.Packages()) == 0 {
= append(, "module does not have any packages")
}
if len() != 0 {
return fmt.Errorf("cannot insert module %q: %s", .Version, strings.Join(, ", "))
}
return nil
}
func ( *DB) ( context.Context, int, []*licenses.License) ( error) {
defer derrors.WrapStack(&, "compareLicenses(ctx, %d)", )
, := .getModuleLicenses(, )
if != nil {
return
}
:= map[string]bool{}
for , := range {
[.FilePath] = true
}
for , := range {
if , := [.FilePath]; ! {
return fmt.Errorf("expected license %q in module: %w", .FilePath, derrors.DBModuleInsertInvalid)
}
}
return nil
}
func ( *DB) ( context.Context, *internal.Module) ( error) {
defer derrors.WrapStack(&, "comparePaths(ctx, %q, %q)", .ModulePath, .Version)
, := .getPathsInModule(, .ModulePath, .Version)
if != nil {
return
}
:= map[string]bool{}
for , := range .Units {
[.Path] = true
}
for , := range {
if , := [.path]; ! {
return fmt.Errorf("expected unit %q in module: %w", .path, derrors.DBModuleInsertInvalid)
}
}
return nil
}
const = `DELETE FROM modules WHERE module_path=$1 AND version=$2`
if , := .Exec(, , , ); != nil {
return
}
if _, = .Exec(, `DELETE FROM version_map WHERE module_path = $1 AND resolved_version = $2`, , ); != nil {
return
}
if _, = .Exec(, `DELETE FROM search_documents WHERE module_path = $1 AND version = $2`, , ); != nil {
return
}
var int
= .QueryRow(, `SELECT 1 FROM modules WHERE module_path=$1 LIMIT 1`, ).Scan(&)
if != sql.ErrNoRows || == nil {
return
_, = .Exec(, `DELETE FROM imports_unique WHERE from_module_path = $1`, )
return
})
}
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |