shared

package
v0.0.0-...-16f8954 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2022 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// LogListMax - do not log lists longer than 30 elements, display list counts instead
	LogListMax = 30
	// DateFormat - format date as YYYY-MM-DD
	DateFormat = "2006-01-02"
	// DefaultRole - default enrollment role
	DefaultRole = "Contributor"
	// ContributorRole - Contributor
	ContributorRole = "Contributor"
	// MaintainerRole - Maintainer
	MaintainerRole = "Maintainer"
	// FetchSize - fetch size for _sql
	FetchSize = 20000
	// MaxAggsSize - maximum number of results to get for top contributors
	MaxAggsSize = 10000
	// CacheTimeResolution - when caching top contributors from and to parameters are rounded using this parameter (ms)
	CacheTimeResolution = 10800000 // 3 hours 10,800,000 ms
	// ESCacheTTL - used by ES query
	ESCacheTTL = "now-3h"
)

Variables

View Source
var (
	// GRedactedMtx - mutex protecting GRedacted
	GRedactedMtx = &sync.Mutex{}
	// GRedacted - keep redacted string that shoudl not be returned to the client
	GRedacted = map[string]struct{}{}
	// GSQLOut - if set displays all SQLs that are executed (if not set, only failed ones)
	GSQLOut bool
	// GSyncURL - used to trigger ssaw sync
	GSyncURL string
	// GSlugMappingMtx - mutex protecting GDA2SF and GSF2DA
	GSlugMappingMtx = &sync.Mutex{}
	// GDA2SF - map DA name to SF name
	GDA2SF map[string]string
	// GSF2DA - map SF name to DA name
	GSF2DA map[string]string
	// MinPeriodDate - default start data for enrollments
	MinPeriodDate = time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC)
	// MaxPeriodDate - default end date for enrollments
	MaxPeriodDate = time.Date(2100, 1, 1, 0, 0, 0, 0, time.UTC)
	// Roles - all currently defined roles
	Roles = []string{"Contributor", "Maintainer"}
	// TopContributorsCacheTTL - top contributors cache TTL (3 hours)
	TopContributorsCacheTTL = time.Duration(3) * time.Hour
	// TopContributorsDataSources - defined data sources
	TopContributorsDataSources = map[string]struct{}{
		"git":          {},
		"github":       {},
		"gerrit":       {},
		"jira":         {},
		"confluence":   {},
		"bugzilla":     {},
		"bugzillarest": {},
	}
	// DataSourceTypesSortOrder - order of data source types
	DataSourceTypesSortOrder = map[string]int{
		"git":                 1,
		"github/pull_request": 2,
		"gerrit":              3,
		"jira":                4,
		"github/issue":        5,
		"bugzilla":            6,
		"bugzillarest":        7,
		"confluence":          8,
	}
	// DataSourcesFields - predefined data for data source types
	// TOPCON
	DataSourcesFields = map[string]*models.ConfiguredDataSourcesFields{
		"git": {
			Key:  "git",
			Name: "Code",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "git_commits", Name: "Commits"},
				{Key: "git_lines_added", Name: "LOC Added"},
				{Key: "git_lines_changed", Name: "LOC Modified"},
				{Key: "git_lines_removed", Name: "LOC Deleted"},
			},
		},
		"github/issue": {
			Key:  "github/issue",
			Name: "Github Issues",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "github_issue_average_time_open_days", Name: "Issues Avg Days in Open"},
				{Key: "github_issue_issues_created", Name: "Issues Created"},
				{Key: "github_issue_issues_assigned", Name: "Issues Assigned"},
				{Key: "github_issue_issues_closed", Name: "Issues Closed"},
				{Key: "github_issue_issues_comments", Name: "Issues Comments"},
			},
		},
		"github/pull_request": {
			Key:  "github/pull_request",
			Name: "Github PRs",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "github_pull_request_prs_created", Name: "PRs Created"},
				{Key: "github_pull_request_prs_open", Name: "PRs Open"},
				{Key: "github_pull_request_prs_closed", Name: "PRs Closed"},
				{Key: "github_pull_request_prs_merged", Name: "PRs Merged"},
				{Key: "github_pull_request_prs_reviewed", Name: "PRs Reviewed"},
				{Key: "github_pull_request_prs_approved", Name: "PRs Approved"},
				{Key: "github_pull_request_prs_review_comments", Name: "PRs Review Comments"},
				{Key: "github_pull_request_prs_comment_activity", Name: "PRs Comment Activity"},
			},
		},
		"gerrit": {
			Key:  "gerrit",
			Name: "Gerrit",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "gerrit_approvals", Name: "Approvals"},
				{Key: "gerrit_changesets", Name: "Active Changesets"},
				{Key: "gerrit_merged_changesets", Name: "Merged Changesets"},
				{Key: "gerrit_comments", Name: "Review Comments"},
			},
		},
		"bugzilla": {
			Key:  "bugzilla",
			Name: "Bugzilla",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "bugzilla_issues_assigned", Name: "Issues Assigned"},
				{Key: "bugzilla_issues_created", Name: "Issues Created"},
				{Key: "bugzilla_issues_closed", Name: "Issues Closed"},
				{Key: "bugzilla_average_issue_open_days", Name: "Issues Avg Days in Open"},
			},
		},
		"bugzillarest": {
			Key:  "bugzillarest",
			Name: "Bugzilla",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "bugzilla_issues_assigned", Name: "Issues Assigned"},
				{Key: "bugzilla_issues_created", Name: "Issues Created"},
				{Key: "bugzilla_issues_closed", Name: "Issues Closed"},
				{Key: "bugzilla_average_issue_open_days", Name: "Issues Avg Days in Open"},
			},
		},
		"jira": {
			Key:  "jira",
			Name: "Jira",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "jira_comments", Name: "Comments"},
				{Key: "jira_issues_assigned", Name: "Issues Assigned"},
				{Key: "jira_issues_created", Name: "Issues Created"},
				{Key: "jira_issues_closed", Name: "Issues Closed"},
				{Key: "jira_average_issue_open_days", Name: "Issues Avg Days in Open"},
			},
		},
		"confluence": {
			Key:  "confluence",
			Name: "Confluence",
			DataTypes: []*models.DataSourceTypeItems{
				{Key: "confluence_comments", Name: "Comments"},
				{Key: "confluence_blog_posts", Name: "Posts"},
				{Key: "confluence_pages_created", Name: "Pages Created"},
				{Key: "confluence_pages_edited", Name: "Pages Edited"},
				{Key: "confluence_attachments", Name: "Attachments"},
				{Key: "confluence_last_action_date", Name: "Last Update"},
				{Key: "confluence_days_since_last_documentation", Name: "Days Since Last Documentation"},
			},
		},
	}
	// EmailRegex - to match the email address
	EmailRegex = regexp.MustCompile("^[][a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
	// WhiteSpace - whitespace regexp
	WhiteSpace = regexp.MustCompile(`\s+`)
)

Functions

This section is empty.

Types

type LocalAllOutput

type LocalAllOutput struct {
	*models.AllOutput
}

LocalAllOutput - embed to add Sortkey() method

func (*LocalAllOutput) SortKey

func (a *LocalAllOutput) SortKey(recursive bool) (key string)

SortKey - defines sort order for profiles

type LocalEnrollmentShortOutput

type LocalEnrollmentShortOutput struct {
	*models.EnrollmentShortOutput
}

LocalEnrollmentShortOutput - embed to add Sortkey() method

func (*LocalEnrollmentShortOutput) SortKey

func (e *LocalEnrollmentShortOutput) SortKey() (key string)

SortKey - defines sort order for enrollments

type LocalIdentity

type LocalIdentity struct {
	*models.IdentityDataOutput
}

LocalIdentity - to display data inside pointers

func (*LocalIdentity) String

func (p *LocalIdentity) String() (s string)

type LocalIdentityShortOutput

type LocalIdentityShortOutput struct {
	*models.IdentityShortOutput
}

LocalIdentityShortOutput - embed to add Sortkey() method

func (*LocalIdentityShortOutput) SortKey

func (i *LocalIdentityShortOutput) SortKey() (key string)

SortKey - defines sort order for identities

type LocalOrganization

type LocalOrganization struct {
	*models.OrganizationDataOutput
}

LocalOrganization - to display data inside pointers

func (*LocalOrganization) String

func (p *LocalOrganization) String() (s string)

type LocalProfile

type LocalProfile struct {
	*models.ProfileDataOutput
}

LocalProfile - to display data inside pointers

func (*LocalProfile) String

func (p *LocalProfile) String() (s string)

type LocalUniqueIdentity

type LocalUniqueIdentity struct {
	*models.UniqueIdentityDataOutput
}

LocalUniqueIdentity - to display data inside pointers

func (*LocalUniqueIdentity) String

func (p *LocalUniqueIdentity) String() (s string)

type ServiceInterface

type ServiceInterface interface {
	// Formatting data for logs
	ToLocalOrganizations([]*models.OrganizationDataOutput) []interface{}
	ToLocalDomains([]*models.DomainDataOutput) []interface{}
	ToLocalNestedOrganizations([]*models.OrganizationNestedDataOutput) []interface{}
	ToLocalNestedUniqueIdentities([]*models.UniqueIdentityNestedDataOutput) []interface{}
	ToLocalNestedUniqueIdentity(*models.UniqueIdentityNestedDataOutput) interface{}
	ToLocalNestedEnrollments([]*models.EnrollmentNestedDataOutput) []interface{}
	ToLocalMatchingBlacklist([]*models.MatchingBlacklistOutput) []interface{}
	ToLocalUnaffiliatedObj(*models.GetUnaffiliatedOutput) []interface{}
	ToLocalUnaffiliated([]*models.UnaffiliatedDataOutput) []interface{}
	ToLocalProfile(*models.ProfileDataOutput) *LocalProfile
	ToLocalProfiles([]*models.ProfileDataOutput) []*LocalProfile
	ToLocalIdentity(*models.IdentityDataOutput) *LocalIdentity
	ToLocalIdentities([]*models.IdentityDataOutput) []*LocalIdentity
	ToLocalUniqueIdentity(*models.UniqueIdentityDataOutput) *LocalUniqueIdentity
	ToLocalOrganization(*models.OrganizationDataOutput) *LocalOrganization
	ToLocalEnrollments([]*models.EnrollmentDataOutput) []interface{}
	ToLocalTopContributorsFlatObj(*models.TopContributorsFlatOutput) []interface{}
	ToLocalTopContributorsFlat([]*models.ContributorFlatStats) []interface{}
	ToLocalProfileNestedRolls(*models.ProfileNestedRolls) interface{}
	// shared DB functions
	QueryOut(string, ...interface{})
	QueryDB(*sqlx.DB, string, ...interface{}) (*sql.Rows, error)
	QueryTX(*sql.Tx, string, ...interface{}) (*sql.Rows, error)
	Query(*sqlx.DB, *sql.Tx, string, ...interface{}) (*sql.Rows, error)
	ExecDB(*sqlx.DB, string, ...interface{}) (sql.Result, error)
	ExecTX(*sql.Tx, string, ...interface{}) (sql.Result, error)
	Exec(*sqlx.DB, *sql.Tx, string, ...interface{}) (sql.Result, error)
	// Other utils
	GetThreadsNum() int
	Now() *strfmt.DateTime
	TimeParseAny(string) (time.Time, error)
	DayStart(time.Time) time.Time
	MonthStart(time.Time) time.Time
	YearStart(time.Time) time.Time
	RoundMSTime(int64) int64
	JSONEscape(string) string
	StripUnicode(string) string
	ToCaseInsensitiveRegexp(string) string
	SpecialUnescape(string) string
	SanitizeShortProfile(*models.AllOutput, bool)
	SanitizeShortIdentity(*models.IdentityShortOutput, bool)
	SanitizeShortEnrollment(*models.EnrollmentShortOutput, bool)
	SanitizeIdentity(*models.IdentityDataOutput)
	SanitizeProfile(*models.ProfileDataOutput)
	// Mapping
	DA2SF(string) string
	SF2DA(string) string
	AryDA2SF([]string) string
	UUDA2SF(*models.UniqueIdentityNestedDataOutput)
	ListProfilesDA2SF(*models.GetListProfilesOutput)
	ProfileEnrollmentsDA2SF(*models.GetProfileEnrollmentsDataOutput)
	ListProjectsDA2SF(*models.ListProjectsOutput)
	AllDA2SF(*models.AllArrayOutput)
	AllSF2DA([]*models.AllOutput)
	ProfileNestedRollsDA2SF(*models.ProfileNestedRolls)
}

ServiceInterface - Shared API interface

type ServiceStruct

type ServiceStruct struct {
}

ServiceStruct - Shared API Struct

func (*ServiceStruct) AllDA2SF

func (s *ServiceStruct) AllDA2SF(data *models.AllArrayOutput)

AllDA2SF - map DA name to SF name

func (*ServiceStruct) AllSF2DA

func (s *ServiceStruct) AllSF2DA(data []*models.AllOutput)

AllSF2DA - map SF name to DA name

func (*ServiceStruct) AryDA2SF

func (s *ServiceStruct) AryDA2SF(da []string) (sf string)

AryDA2SF - map DA names array to SF names string "," separated (fallback to no change)

func (*ServiceStruct) DA2SF

func (s *ServiceStruct) DA2SF(da string) (sf string)

DA2SF - map DA name to SF name (fallback to no change)

func (*ServiceStruct) DBDateTime

func (s *ServiceStruct) DBDateTime() (*strfmt.DateTime, error)

DBDateTime returns the time right now formatted in the way expected by the db `2006-01-02 15:04:05`

func (*ServiceStruct) DayStart

func (s *ServiceStruct) DayStart(dt time.Time) time.Time

DayStart - round date to day start

func (*ServiceStruct) Exec

func (s *ServiceStruct) Exec(db *sqlx.DB, tx *sql.Tx, query string, args ...interface{}) (sql.Result, error)

Exec - execute db query with transaction if provided

func (*ServiceStruct) ExecDB

func (s *ServiceStruct) ExecDB(db *sqlx.DB, query string, args ...interface{}) (res sql.Result, err error)

ExecDB - execute DB query without transaction

func (*ServiceStruct) ExecTX

func (s *ServiceStruct) ExecTX(db *sql.Tx, query string, args ...interface{}) (res sql.Result, err error)

ExecTX - execute DB query with transaction

func (*ServiceStruct) GetThreadsNum

func (s *ServiceStruct) GetThreadsNum() int

GetThreadsNum - returns number of available threads

func (*ServiceStruct) JSONEscape

func (s *ServiceStruct) JSONEscape(str string) string

JSONEscape - escape string for JSON to avoid injections

func (*ServiceStruct) ListProfilesDA2SF

func (s *ServiceStruct) ListProfilesDA2SF(data *models.GetListProfilesOutput)

ListProfilesDA2SF - map DA name to SF name

func (*ServiceStruct) ListProjectsDA2SF

func (s *ServiceStruct) ListProjectsDA2SF(data *models.ListProjectsOutput)

ListProjectsDA2SF - map DA name to SF name

func (*ServiceStruct) MonthStart

func (s *ServiceStruct) MonthStart(dt time.Time) time.Time

MonthStart - round date to month start

func (*ServiceStruct) Now

func (s *ServiceStruct) Now() *strfmt.DateTime

Now - return date now

func (*ServiceStruct) ProfileEnrollmentsDA2SF

func (s *ServiceStruct) ProfileEnrollmentsDA2SF(data *models.GetProfileEnrollmentsDataOutput)

ProfileEnrollmentsDA2SF - map DA name to SF name

func (*ServiceStruct) ProfileNestedRollsDA2SF

func (s *ServiceStruct) ProfileNestedRollsDA2SF(profile *models.ProfileNestedRolls)

ProfileNestedRollsDA2SF - map DA name to SF name

func (*ServiceStruct) Query

func (s *ServiceStruct) Query(db *sqlx.DB, tx *sql.Tx, query string, args ...interface{}) (*sql.Rows, error)

Query - query DB using transaction if provided

func (*ServiceStruct) QueryDB

func (s *ServiceStruct) QueryDB(db *sqlx.DB, query string, args ...interface{}) (rows *sql.Rows, err error)

QueryDB - query database without transaction

func (*ServiceStruct) QueryOut

func (s *ServiceStruct) QueryOut(query string, args ...interface{})

QueryOut - display DB query

func (*ServiceStruct) QueryTX

func (s *ServiceStruct) QueryTX(db *sql.Tx, query string, args ...interface{}) (rows *sql.Rows, err error)

QueryTX - query database with transaction

func (*ServiceStruct) QueryToStringArray

func (s *ServiceStruct) QueryToStringArray(db *sqlx.DB, tx *sql.Tx, query string, args ...interface{}) (res []string)

QueryToStringArray - execute SQL query returning multiple rows each containitg a single string column

func (*ServiceStruct) QueryToStringIntArrays

func (s *ServiceStruct) QueryToStringIntArrays(db *sqlx.DB, tx *sql.Tx, query string, args ...interface{}) (sa []string, ia []int64)

QueryToStringIntArrays - execute SQL query returning multiple rows each containitg (string,int64)

func (*ServiceStruct) RoundMSTime

func (s *ServiceStruct) RoundMSTime(t int64) int64

RoundMSTime - round using CacheTimeResolution (3 hours)

func (*ServiceStruct) SF2DA

func (s *ServiceStruct) SF2DA(sf string) (da string)

SF2DA - map SF name to DA name (fallback to no change)

func (*ServiceStruct) SanitizeIdentity

func (s *ServiceStruct) SanitizeIdentity(identity *models.IdentityDataOutput)

SanitizeIdentity - trim white spaces

func (*ServiceStruct) SanitizeProfile

func (s *ServiceStruct) SanitizeProfile(prof *models.ProfileDataOutput)

SanitizeProfile - trim white spaces

func (*ServiceStruct) SanitizeShortEnrollment

func (s *ServiceStruct) SanitizeShortEnrollment(enrollment *models.EnrollmentShortOutput, isGet bool)

SanitizeShortEnrollment - trim white spaces

func (*ServiceStruct) SanitizeShortIdentity

func (s *ServiceStruct) SanitizeShortIdentity(identity *models.IdentityShortOutput, isGet bool)

SanitizeShortIdentity - trim white spaces and email @/!

func (*ServiceStruct) SanitizeShortProfile

func (s *ServiceStruct) SanitizeShortProfile(prof *models.AllOutput, isGet bool)

SanitizeShortProfile - trim white spaces, email @/! and dependent objects

func (*ServiceStruct) SpecialUnescape

func (s *ServiceStruct) SpecialUnescape(str string) (ostr string)

SpecialUnescape - some special characters are JSON escaped - but we must do it to avid injections This function restores them, currently: &

func (*ServiceStruct) StripUnicode

func (s *ServiceStruct) StripUnicode(str string) string

StripUnicode - strip special characters and remove non-ascii chars ł->l, ą->a etc.

func (*ServiceStruct) TimeParseAny

func (s *ServiceStruct) TimeParseAny(dtStr string) (time.Time, error)

TimeParseAny - parse time from string

func (*ServiceStruct) ToCaseInsensitiveRegexp

func (s *ServiceStruct) ToCaseInsensitiveRegexp(str string) (ret string)

ToCaseInsensitiveRegexp - transform string say "abc" to ".*[aA][bB][cC].*"

func (*ServiceStruct) ToLocalDomains

func (s *ServiceStruct) ToLocalDomains(ia []*models.DomainDataOutput) (oa []interface{})

ToLocalDomains - to display values inside pointers

func (*ServiceStruct) ToLocalEnrollments

func (s *ServiceStruct) ToLocalEnrollments(ia []*models.EnrollmentDataOutput) (oa []interface{})

ToLocalEnrollments - to display values inside pointers

func (*ServiceStruct) ToLocalIdentities

func (s *ServiceStruct) ToLocalIdentities(ia []*models.IdentityDataOutput) (oa []*LocalIdentity)

ToLocalIdentities - to display values inside pointers

func (*ServiceStruct) ToLocalIdentity

func (s *ServiceStruct) ToLocalIdentity(i *models.IdentityDataOutput) (o *LocalIdentity)

ToLocalIdentity - to display values inside pointers

func (*ServiceStruct) ToLocalMatchingBlacklist

func (s *ServiceStruct) ToLocalMatchingBlacklist(ia []*models.MatchingBlacklistOutput) (oa []interface{})

ToLocalMatchingBlacklist - to display values inside pointers

func (*ServiceStruct) ToLocalNestedEnrollments

func (s *ServiceStruct) ToLocalNestedEnrollments(ia []*models.EnrollmentNestedDataOutput) (oa []interface{})

ToLocalNestedEnrollments - to display values inside pointers

func (*ServiceStruct) ToLocalNestedOrganizations

func (s *ServiceStruct) ToLocalNestedOrganizations(ia []*models.OrganizationNestedDataOutput) (oa []interface{})

ToLocalNestedOrganizations - to display values inside pointers

func (*ServiceStruct) ToLocalNestedUniqueIdentities

func (s *ServiceStruct) ToLocalNestedUniqueIdentities(ia []*models.UniqueIdentityNestedDataOutput) (oa []interface{})

ToLocalNestedUniqueIdentities - to display values inside pointers

func (*ServiceStruct) ToLocalNestedUniqueIdentity

func (s *ServiceStruct) ToLocalNestedUniqueIdentity(i *models.UniqueIdentityNestedDataOutput) (o interface{})

ToLocalNestedUniqueIdentity - to display values inside pointers

func (*ServiceStruct) ToLocalOrganization

func (s *ServiceStruct) ToLocalOrganization(i *models.OrganizationDataOutput) (o *LocalOrganization)

ToLocalOrganization - to display values inside pointers

func (*ServiceStruct) ToLocalOrganizations

func (s *ServiceStruct) ToLocalOrganizations(ia []*models.OrganizationDataOutput) (oa []interface{})

ToLocalOrganizations - to display values inside pointers

func (*ServiceStruct) ToLocalProfile

func (s *ServiceStruct) ToLocalProfile(i *models.ProfileDataOutput) (o *LocalProfile)

ToLocalProfile - to display values inside pointers

func (*ServiceStruct) ToLocalProfileNestedRolls

func (s *ServiceStruct) ToLocalProfileNestedRolls(i *models.ProfileNestedRolls) (o interface{})

ToLocalProfileNestedRolls - to display values inside pointers

func (*ServiceStruct) ToLocalProfiles

func (s *ServiceStruct) ToLocalProfiles(ia []*models.ProfileDataOutput) (oa []*LocalProfile)

ToLocalProfiles - to display values inside pointers

func (*ServiceStruct) ToLocalTopContributorsFlat

func (s *ServiceStruct) ToLocalTopContributorsFlat(ia []*models.ContributorFlatStats) (oa []interface{})

ToLocalTopContributorsFlat - to display values inside pointers

func (*ServiceStruct) ToLocalTopContributorsFlatObj

func (s *ServiceStruct) ToLocalTopContributorsFlatObj(ia *models.TopContributorsFlatOutput) (oa []interface{})

ToLocalTopContributorsFlatObj - to display values inside pointers

func (*ServiceStruct) ToLocalUnaffiliated

func (s *ServiceStruct) ToLocalUnaffiliated(ia []*models.UnaffiliatedDataOutput) (oa []interface{})

ToLocalUnaffiliated - to display values inside pointers

func (*ServiceStruct) ToLocalUnaffiliatedObj

func (s *ServiceStruct) ToLocalUnaffiliatedObj(ia *models.GetUnaffiliatedOutput) (oa []interface{})

ToLocalUnaffiliatedObj - to display values inside pointers

func (*ServiceStruct) ToLocalUniqueIdentity

func (s *ServiceStruct) ToLocalUniqueIdentity(i *models.UniqueIdentityDataOutput) (o *LocalUniqueIdentity)

ToLocalUniqueIdentity - to display values inside pointers

func (*ServiceStruct) UUDA2SF

UUDA2SF - map DA name to SF name

func (*ServiceStruct) YearStart

func (s *ServiceStruct) YearStart(dt time.Time) time.Time

YearStart - round date to year start

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL