Copyright 2021 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.
Functions for cleaning the database of unwanted module versions.

package postgres

import (
	
	

	
)
A ModuleVersion holds a module path and version.
type ModuleVersion struct {
	ModulePath string
	Version    string
}

func ( ModuleVersion) () string {
	return .ModulePath + "@" + .Version
}
GetModuleVersionsToClean returns module versions that can be removed from the database. Only module versions that were updated more than daysOld days ago will be considered. At most limit module versions will be returned.
func ( *DB) ( context.Context, ,  int) ( []ModuleVersion,  error) {
	defer derrors.WrapStack(&, "GetModuleVersionsToClean(%d, %d)", , )
Get all pseudo-versions that were added before the given number of days. Then remove: - The ones that are the latest versions for their module, - The ones in search_documents (since the latest version of a package might be at an older version), - The ones that the master or main branch resolves to.
	 := `
		SELECT module_path, version
		FROM modules
		WHERE version_type = 'pseudo'
		AND CURRENT_TIMESTAMP - updated_at > make_interval(days => $1)
		EXCEPT (
			SELECT p.path, l.good_version
			FROM latest_module_versions l
			INNER JOIN paths p ON p.id = l.module_path_id
			WHERE good_version != ''
		)
		EXCEPT (
			SELECT module_path, version
			FROM search_documents
		)
		EXCEPT (
			SELECT module_path, resolved_version
			FROM version_map
			WHERE requested_version IN ('master', 'main')
		)
		LIMIT $2
	`

	 = .db.RunQuery(, , func( *sql.Rows) error {
		var  ModuleVersion
		if  := .Scan(&.ModulePath, &.Version);  != nil {
			return 
		}
		 = append(, )
		return nil
	}, , )
	if  != nil {
		return nil, 
	}
	return , nil
}
CleanModuleVersions deletes each module version from the DB and marks it as cleaned in module_version_states.
func ( *DB) ( context.Context,  []ModuleVersion,  string) ( error) {
	defer derrors.Wrap(&, "CleanModuleVersions(%d modules)", len())

	 := derrors.ToStatus(derrors.Cleaned)
	for ,  := range  {
		if  := .UpdateModuleVersionStatus(, .ModulePath, .Version, , );  != nil {
			return 
		}
		if  := .DeleteModule(, .ModulePath, .Version);  != nil {
			return 
		}
	}
	return nil
}
CleanModule deletes all versions of the given module path from the DB and marks them as cleaned in module_version_states.
func ( *DB) ( context.Context, ,  string) ( error) {
	defer derrors.Wrap(&, "CleanModule(%q)", )

	var  []ModuleVersion
	 = .db.RunQuery(, `
		SELECT version
		FROM modules
		WHERE module_path = $1
	`, func( *sql.Rows) error {
		var  string
		if  := .Scan(&);  != nil {
			return 
		}
		 = append(, ModuleVersion{, })
		return nil
	}, )
	if  != nil {
		return 
	}
	return .CleanModuleVersions(, , )