Copyright 2019 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 postgres

import (
	
	
	
	
	
	
	

	
	
	
)
GetNestedModules returns the latest major version of all nested modules given a modulePath path prefix with or without major version.
func ( *DB) ( context.Context,  string) ( []*internal.ModuleInfo,  error) {
	defer derrors.WrapStack(&, "GetNestedModules(ctx, %v)", )
	defer middleware.ElapsedStat(, "GetNestedModules")()

	 := `
		SELECT DISTINCT ON (series_path)
			m.module_path,
			m.version,
			m.commit_time,
			m.redistributable,
			m.has_go_mod,
			m.source_info
		FROM
			modules m
		WHERE
			m.module_path LIKE $1 || '/%'
		ORDER BY
			m.series_path,
			m.incompatible,
			m.version_type = 'release' DESC,
			m.sort_version DESC;
	`

	var  []*internal.ModuleInfo
	 := func( *sql.Rows) error {
		,  := scanModuleInfo(.Scan)
		if  != nil {
			return fmt.Errorf("rows.Scan(): %v", )
		}
		,  := .IsExcluded(, .ModulePath)
		if  != nil {
			return 
		}
		if ! {
			 = append(, )
		}
		return nil
	}
	 := internal.SeriesPathForModule()
	if  := .db.RunQuery(, , , );  != nil {
		return nil, 
	}

	if  := populateLatestInfos(, , );  != nil {
		return nil, 
	}

	return , nil
}
GetImportedBy fetches and returns all of the packages that import the package with path. The returned error may be checked with derrors.IsInvalidArgument to determine if it resulted from an invalid package path or version. Instead of supporting pagination, this query runs with a limit.
func ( *DB) ( context.Context, ,  string,  int) ( []string,  error) {
	defer derrors.WrapStack(&, "GetImportedBy(ctx, %q, %q)", , )
	defer middleware.ElapsedStat(, "GetImportedBy")()

	if  == "" {
		return nil, fmt.Errorf("pkgPath cannot be empty: %w", derrors.InvalidArgument)
	}
	 := `
		SELECT
			DISTINCT from_path
		FROM
			imports_unique
		WHERE
			to_path = $1
		AND
			from_module_path <> $2
		ORDER BY
			from_path
		LIMIT $3`

	return collectStrings(, .db, , , , )
}
GetImportedByCount returns the number of packages that import pkgPath.
func ( *DB) ( context.Context, ,  string) ( int,  error) {
	defer derrors.WrapStack(&, "GetImportedByCount(ctx, %q, %q)", , )
	defer middleware.ElapsedStat(, "GetImportedByCount")()

	if  == "" {
		return 0, fmt.Errorf("pkgPath cannot be empty: %w", derrors.InvalidArgument)
	}
	 := `
		SELECT imported_by_count
		FROM
			search_documents
		WHERE
			package_path = $1
	`
	var  int
	 = .db.QueryRow(, , ).Scan(&)
	switch  {
	case sql.ErrNoRows:
		return 0, nil
	case nil:
		return , nil
	default:
		return 0, 
	}
}
GetModuleInfo fetches a module version from the database with the primary key (module_path, version).
func ( *DB) ( context.Context, ,  string) ( *internal.ModuleInfo,  error) {
	defer derrors.WrapStack(&, "GetModuleInfo(ctx, %q, %q)", , )

	 := `
		SELECT
			module_path,
			version,
			commit_time,
			redistributable,
			has_go_mod,
			source_info
		FROM
			modules
		WHERE
			module_path = $1
			AND version = $2;`

	 := .db.QueryRow(, , , )
	,  := scanModuleInfo(.Scan)
	if  == sql.ErrNoRows {
		return nil, derrors.NotFound
	}
	if  != nil {
		return nil, fmt.Errorf("row.Scan(): %v", )
	}

	if  := populateLatestInfo(, , );  != nil {
		return nil, 
	}
	return , nil
}
jsonbScanner scans a jsonb value into a Go value.
type jsonbScanner struct {
	ptr interface{} // a pointer to a Go struct or other JSON-serializable value
}

func ( jsonbScanner) ( interface{}) ( error) {
	defer derrors.Wrap(&, "jsonbScanner(%+v)", )

	 := reflect.ValueOf(.ptr)
*s.ptr = nil
		.Elem().Set(reflect.Zero(.Elem().Type()))
		return nil
	}
	,  := .([]byte)
	if ! {
		return errors.New("not a []byte")
v := &[type of *s.ptr]
	 := reflect.New(.Elem().Type())
	if  := json.Unmarshal(, .Interface());  != nil {
		return 
	}
*s.ptr = *v
	.Elem().Set(.Elem())
	return nil
}
scanModuleInfo constructs an *internal.ModuleInfo from the given scanner.
func ( func( ...interface{}) error) (*internal.ModuleInfo, error) {
	var  internal.ModuleInfo
	if  := (&.ModulePath, &.Version, &.CommitTime,
		&.IsRedistributable, &.HasGoMod, jsonbScanner{&.SourceInfo});  != nil {
		return nil, 
	}
	return &, nil
}
packageLinkRegexp matches cross-package identifier links that have been generated by the dochtml package. At the time this hack was added, these links are all constructed to have either the form <a href="/pkg/[path]">[name]</a> or the form <a href="/pkg/[path]#identifier">[name]</a> The packageLinkRegexp mutates these links as follows: - remove the now unnecessary '/pkg' path prefix
var packageLinkRegexp = regexp.MustCompile(`(<a href="/)pkg/([^?#"]+)((?:#[^"]*)?">.*?</a>)`)
removePkgPrefix removes the /pkg path prefix from links in docHTML. See documentation for packageLinkRegexp for explanation and TestRemovePkgPrefix for examples. It preserves the safety of its argument. That is, if docHTML is safe from XSS attacks, so is removePkgPrefix(docHTML). Although we don't add "/pkg" to links after https://golang.org/cl/259101, do not remove this function until all databases have been reprocessed.
func ( string) string {
	return packageLinkRegexp.ReplaceAllString(, `$1$2$3`)