in internal/postgres/insert_module.go [635:760]
func (db *DB) ReconcileSearch(ctx context.Context, modulePath, version string, status int) (err error) {
defer derrors.WrapStack(&err, "ReconcileSearch(%q)", modulePath)
return db.db.Transact(ctx, sql.LevelRepeatableRead, func(tx *database.DB) error {
// Hold the lock on the module path throughout.
if err := lock(ctx, tx, modulePath); err != nil {
return err
}
lmv, _, err := getLatestModuleVersions(ctx, tx, modulePath)
if err != nil {
return err
}
if lmv == nil {
log.Debugf(ctx, "ReconcileSearch(%q): no latest-version info", modulePath)
return nil
}
// Determine if this is an alternative module. The
// isAlternativeModulePath function checks the DB, but at the time
// ReconcileSearch is called, we haven't added the current module
// version's status to the DB, so we use the version and status
// arguments.
alt := version == lmv.CookedVersion && status == derrors.ToStatus(derrors.AlternativeModule)
if !alt {
alt, err = isAlternativeModulePath(ctx, tx, modulePath)
if err != nil {
return err
}
}
if alt || lmv.GoodVersion == "" {
// A missing GoodVersion means that there are no good versions
// remaining. In that case, or if this is an alternative module, we
// should remove the module from search.
if err := deleteModuleFromSearchDocuments(ctx, tx, modulePath); err != nil {
return err
}
if err := deleteModuleFromImportsUnique(ctx, tx, modulePath); err != nil {
return err
}
log.Debugf(ctx, "ReconcileSearch(%q): alternative or no good version; removed from search_documents and imports_unique", modulePath)
return nil
}
// Is the latest good version in search_documents, or is there a longer module path?
var x int
switch err := tx.QueryRow(ctx, `
SELECT 1
FROM search_documents
WHERE (module_path = $1 AND version = $2)
OR module_path LIKE $1 || '/%'
`, modulePath, lmv.GoodVersion).Scan(&x); err {
case sql.ErrNoRows:
break
case nil:
log.Debugf(ctx, "ReconcileSearch(%q): good version %s or suffix module path found in search_documents; doing nothing",
modulePath, lmv.GoodVersion)
return nil
default:
return err
}
// The latest good version is not in search_documents, and this is
// not an alternative module path. Insert the latest good version.
// Read the module information at the latest good version.
pkgMetas, err := getPackagesInUnit(ctx, tx, modulePath, modulePath, lmv.GoodVersion, -1, db.bypassLicenseCheck)
if err != nil {
return err
}
// We only need the readme for the module.
readme, err := getModuleReadme(ctx, tx, modulePath, lmv.GoodVersion)
if err != nil && !errors.Is(err, derrors.NotFound) {
return err
}
// Delete packages not in this version.
var pkgPaths []string
for _, pkg := range pkgMetas {
pkgPaths = append(pkgPaths, pkg.Path)
}
if err := deleteOtherModulePackagesFromSearchDocuments(ctx, tx, modulePath, pkgPaths); err != nil {
return err
}
// Insert into search_documents.
for _, pkg := range pkgMetas {
if isInternalPackage(pkg.Path) {
continue
}
args := UpsertSearchDocumentArgs{
PackagePath: pkg.Path,
ModulePath: modulePath,
Version: lmv.GoodVersion,
Synopsis: pkg.Synopsis,
}
if pkg.Path == modulePath && readme != nil {
args.ReadmeFilePath = readme.Filepath
args.ReadmeContents = readme.Contents
}
if err := UpsertSearchDocument(ctx, tx, args); err != nil {
return err
}
}
// Remove old rows from imports_unique.
if err := deleteModuleFromImportsUnique(ctx, tx, modulePath); err != nil {
return err
}
// Insert this version's imports into imports_unique.
if _, err := tx.Exec(ctx, `
INSERT INTO imports_unique (from_path, from_module_path, to_path)
SELECT p1.path, m.module_path, p2.path
FROM units u
INNER JOIN imports i ON u.id = i.unit_id
INNER JOIN paths p1 ON p1.id = u.path_id
INNER JOIN modules m ON m.id = u.module_id
INNER JOIN paths p2 ON p2.id = i.to_path_id
WHERE m.module_path = $1 and m.version = $2
`, modulePath, lmv.GoodVersion); err != nil {
return err
}
log.Debugf(ctx, "ReconcileSearch(%q): re-inserted at latest good version %s", modulePath, lmv.GoodVersion)
return nil
})
}