strategy

package
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 14 Imported by: 0

README

Strategy

Overview

A Strategy is a reusable struct that must define 2 functions CheckCriteria() error and ExecuteStrategy() (any, error). A subset of Strategy is ValueStrategy which implements the above alongside another function, SetValue(any). This allows for a Strategy to set a value and rely on it for its purpose.

Strategy Types

Override Strategy

An Override Strategy is a Strategy that does not rely on a value. As such, it is not a ValueStrategy. Only one parameter is defined for this type which is Strategy() (any, error). This function is user defined and allows the behavior to be changed to suit the user's needs. No criteria function is set due to this type not relying on a value, as such CheckCriteria() error simply returns nil and skips validation. This Strategy is meant to be used when you want consistent behavior regardless of the template's value field. Below is the general execution flow for an Override Strategy.

override_strategy_flow.png

Optional Strategy

An Optional Strategy is a Strategy that relies on a value. As such it is a ValueStrategy. The parameters defined for this type of Strategy are the following:

  • Strategy(val any) (any, error): User defined function that uses the stored value of the struct. Returns the result and any errors that occurred in execution.
  • Criteria(val any) error: User defined function which performs type checking for the stored value of type any. Returns an error if the type is deemed invalid.
  • Value any: The stored value set by the SetValue(any) function and is used as the input for the above functions
  • Default any: A user defined default value to be used when the given value for SetValue(any) is nil

Optional Strategy should be used when a default is meant to be used when nil is given as the value from a template. To achieve this, the user defines a Default any parameter. When SetValue(any) runs and is given a nil value, the value parameter is automatically set to Default any. In other words Optional Strategy should be used when you want the option to define the behavior using the value field or leave it to a default. Below is the general execution flow for an Optional Strategy.

optional_strategy_flow.png

Required Strategy

A Required Strategy is a Strategy that relies on a value. As such it is a ValueStrategy. The parameters defined for this type of Strategy are the following:

  • Strategy(val any) (any, error): User defined function that uses the stored value of the struct. Returns the result and any errors that occurred in execution.
  • Criteria(val any) error: User defined function which performs type checking for the stored value of type any. Returns an error if the type is deemed invalid.
  • Value any: The stored value set by the SetValue(any) function and is used as the input for the above functions

Required Strategy should be used when the struct needs a value in order to be used and as such cannot accept nil as one. Even should the user defined Criteria function allow it, a nil check is performed before running the user's Criteria function and will return an error if the Value is nil. Below is the general execution flow for a Required Strategy.

required_strategy_flow.png

Note: The above diagrams aren't telling the whole story. A Strategy is used internally by both the template and parameters package to help with their purposes. As such, the flows above are fragmented parts of a larger process that has been stitched together. It's more of the lifecycle of a Strategy. In reality, the template package is actually responsible for all the steps before ExecuteStrategy() is called. Then, from that point forward it's the parameters package that handles the rest.

Creating Strategies

As you may have noticed, the behavior of a Strategy depends largely on the user defined functions (Strategy() (any, error), Strategy(val any) (any, error) and Criteria(val any) error). This modularity allows users to create their own Strategy based on the above types. The library can then add these new Strategies using predefined functions:

  • AddNewOverrideStrategy(columnType string, codeName string, strategy func() Strategy) error
  • AddNewOptionalStrategy(columnType string, codeName string, strategy func() ValueStrategy) error
  • AddNewRequiredStrategy(columnType string, codeName string, strategy func() ValueStrategy) error

Each function can "hook-in" to the internal systems and allow the Strategy to be recognized when it comes time to generate data. Validation for all 3 is mostly the same, ensuring that an existing Strategy doesn't exist internally i.e. no overwriting existing entries. They also ensure that the given columnType specified is supported and that the new entry follows existing convention. For AddNewOverrideStrategy specifically, it ensures that the Strategy given is not a ValueStrategy.

Note: Because of this explicit need to add the created Strategy using these functions, creating and utilizing your own Strategy is not currently compatible with the CLI tool. For the CLI tool, you are restricted to the Strategies that are already defined. A definitive list of existing Strategies can be found here

Strategy functions over Strategies

The above functions do not take in the Strategy but a function that returns the Strategy. The reason for this is to allow for flexibility. Some Strategies can be shared i.e. the same struct is linked to all columns that use it and some can not. This allows for the user to decide whether an existing struct should be used or if a new one is created each time. An example of this can be seen with the SERIAL code for the INT type. It's behavior matches the auto-incrementing integer of the same name in databases as seen here

If the Strategy is shared i.e. each column uses the same struct the following occurs: incorrect_serial_case This does not follow how the SERIAL keyword works in postgres and thus is not behaving correctly

If this Strategy isn't shared however i.e. each column receives a new copy of the struct: correct_serial_case This does now conform to the expectation

This flexibility allows for both possibilities and can thus let user's be more space efficient if they so choose to be. For example, all instances of Override Strategy that are defined and use gofakeit can be safely shared.

Defined Strategies

For more information on which Strategies are already defined, please read the Existing Strategies file

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddNewOptionalStrategy

func AddNewOptionalStrategy(columnType string, codeName string, strategy func() ValueStrategy) error

AddNewOptionalStrategy adds a strategy function to the internal map, an error is returned if the process fails

func AddNewOverrideStrategy

func AddNewOverrideStrategy(columnType string, codeName string, strategy func() Strategy) error

AddNewOverrideStrategy adds a strategy function to the internal map, an error is returned if the process fails

func AddNewRequiredStrategy

func AddNewRequiredStrategy(columnType string, codeName string, strategy func() ValueStrategy) error

AddNewRequiredStrategy adds a strategy function to the internal map, an error is returned if the process fails

func DeleteStrategy

func DeleteStrategy(columnType, codeName string) error

DeleteStrategy deletes a given strategy from the internal maps and returns any errors. This function cannot affect the default codes, i.e. the codes hardcoded into the library and will return an error if this is attempted. If the code columnType and codename already don't exist in a map, this is considered a no-op

func GetOptionalCodeMap

func GetOptionalCodeMap() map[string]map[string]func() ValueStrategy

GetOptionalCodeMap returns a copy of the internal map for codes of the OptionalStrategy type

func GetOverrideCodeMap

func GetOverrideCodeMap() map[string]map[string]func() Strategy

GetOverrideCodeMap returns a copy of the internal map for codes of the OverrideStrategy type

func GetRequiredCodeMap

func GetRequiredCodeMap() map[string]map[string]func() ValueStrategy

GetRequiredCodeMap returns a copy of the internal map for codes of the RequiredStrategy type

Types

type DeleteDefaultError

type DeleteDefaultError struct {
	// contains filtered or unexported fields
}

func (DeleteDefaultError) Error

func (e DeleteDefaultError) Error() string

type ExistingStrategyError

type ExistingStrategyError struct {
	ColumnType string
	Code       string
}

ExistingStrategyError is an error given when a user tries to overwrite an existing strategy on the internal maps

func (ExistingStrategyError) Error

func (e ExistingStrategyError) Error() string

type ImproperDateStringFormatError

type ImproperDateStringFormatError struct {
	DateString string
}

ImproperDateStringFormatError is an error given when the given date string doesn't match any known format

func (ImproperDateStringFormatError) Error

type ImproperTimeStringFormatError

type ImproperTimeStringFormatError struct {
	TimeString string
}

ImproperTimeStringFormatError is an error given when the given time string doesn't match the time.TimeOnly layout

func (ImproperTimeStringFormatError) Error

type InvalidRegexError

type InvalidRegexError struct {
	Regex string
	Err   error
}

InvalidRegexError is an error given when the regex string, when given to `regexp.compile()`, returns an error

func (InvalidRegexError) Error

func (e InvalidRegexError) Error() string

type NotInRangeError

type NotInRangeError struct {
	// contains filtered or unexported fields
}

NotInRangeError is given when a value isn't in a predefined range which represented as a string

func (NotInRangeError) Error

func (e NotInRangeError) Error() string

type OptionalStrategy

type OptionalStrategy struct {
	Default any
	// contains filtered or unexported fields
}

OptionalStrategy is a type of Strategy that can take in either nil or a valid input as their value

func (*OptionalStrategy) CheckCriteria

func (s *OptionalStrategy) CheckCriteria() error

func (*OptionalStrategy) ExecuteStrategy

func (s *OptionalStrategy) ExecuteStrategy() (any, error)

func (*OptionalStrategy) SetValue

func (s *OptionalStrategy) SetValue(val any)

type OverrideStrategy

type OverrideStrategy struct {
	Strategy func() (any, error)
}

OverrideStrategy is a type of Strategy that doesn't take in a value and simply executes it's given strategy function

func (*OverrideStrategy) CheckCriteria

func (s *OverrideStrategy) CheckCriteria() error

CheckCriteria for the OverrideStrategy returns nil as OverrideStrategy's do not take in a value to evaluate

func (*OverrideStrategy) ExecuteStrategy

func (s *OverrideStrategy) ExecuteStrategy() (any, error)

ExecuteStrategy for the OverrideStrategy executes and returns it's strategy. if the strategy is undefined, i.e. nil, the program logs the failure and exits using log.Fatal

type RandomBoundError

type RandomBoundError struct {
	LowerBound any
	UpperBound any
}

RandomBoundError is an error given when the lower bound of a "RANDOM" code is greater than the upper bound

func (RandomBoundError) Error

func (e RandomBoundError) Error() string

type RequiredParameterNilError

type RequiredParameterNilError struct {
	Name string
}

RequiredParameterNilError is an error given when a required parameter is set to nil

func (RequiredParameterNilError) Error

type RequiredStrategy

type RequiredStrategy struct {
	// contains filtered or unexported fields
}

RequiredStrategy is a type of strategy that requires a non-nil value to be given to it as input

func (*RequiredStrategy) CheckCriteria

func (s *RequiredStrategy) CheckCriteria() error

func (*RequiredStrategy) ExecuteStrategy

func (s *RequiredStrategy) ExecuteStrategy() (any, error)

ExecuteStrategy for the RequiredStrategy executes and returns it's strategy with its value field as input. Before the strategy is run, the program checks the validity using CheckCriteria. If an error occurs at any point, the program logs the failure and exits using log.Fatal

func (*RequiredStrategy) SetValue

func (s *RequiredStrategy) SetValue(val any)

type RequiredValueNilError

type RequiredValueNilError struct{}

RequiredValueNilError is an error given when a nil value is given to a RequiredStrategy and isn't filtered out by its criteria

func (RequiredValueNilError) Error

func (e RequiredValueNilError) Error() string

type Strategy

type Strategy interface {
	ExecuteStrategy() (any, error)
	CheckCriteria() error
}

func GetStrategy

func GetStrategy(columnType, codeName string) (Strategy, error)

GetStrategy returns a strategy from the internal maps based on the columnType and codeName given. It also returns any errors that occurred in the attempt

func NewAddressVarcharStrategy

func NewAddressVarcharStrategy() Strategy

NewAddressVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "ADDRESS" for type "VARCHAR"

func NewCityVarcharStrategy

func NewCityVarcharStrategy() Strategy

NewCityVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "CITY" for type "VARCHAR"

func NewCountryVarcharStrategy

func NewCountryVarcharStrategy() Strategy

NewCountryVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "COUNTRY" for type "VARCHAR"

func NewEmailVarcharStrategy

func NewEmailVarcharStrategy() Strategy

NewEmailVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "EMAIL" for type "VARCHAR"

func NewFirstNameVarcharStrategy

func NewFirstNameVarcharStrategy() Strategy

NewFirstNameVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "FIRSTNAME" for type "VARCHAR"

func NewFullNameVarcharStrategy

func NewFullNameVarcharStrategy() Strategy

NewFullNameVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "FULLNAME" for type "VARCHAR"

func NewLastNameVarcharStrategy

func NewLastNameVarcharStrategy() Strategy

NewLastNameVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "LASTNAME" for type "VARCHAR"

func NewNowDateStrategy

func NewNowDateStrategy() Strategy

NewNowDateStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "NOW" for type "DATE"

func NewNowTimeStrategy

func NewNowTimeStrategy() Strategy

NewNowTimeStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "NOW" for type "TIME"

func NewNullStrategy

func NewNullStrategy() Strategy

NewNullStrategy defines and returns a Strategy of type OverrideStrategy meant to handle the "NUll" code for all types except "UUID"

func NewPhoneVarcharStrategy

func NewPhoneVarcharStrategy() Strategy

NewPhoneVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "PHONE" for type "VARCHAR"

func NewRandomBoolStrategy

func NewRandomBoolStrategy() Strategy

NewRandomBoolStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "RANDOM" for type "BOOL"

func NewUUIDStrategy

func NewUUIDStrategy() Strategy

NewUUIDStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "UUID" for type "UUID"

func NewZipCodeVarcharStrategy

func NewZipCodeVarcharStrategy() Strategy

NewZipCodeVarcharStrategy defines and returns a Strategy of type OverrideStrategy meant to handle code "ZIPCODE" for type "VARCHAR"

type UnexpectedArrayLengthError

type UnexpectedArrayLengthError struct {
	ExpectedLength int
	ActualLength   int
}

UnexpectedArrayLengthError is an error given when the length of the received array doesn't match the expected length

func (UnexpectedArrayLengthError) Error

type UnexpectedTypeError

type UnexpectedTypeError struct {
	ExpectedType string
	ActualType   string
}

UnexpectedTypeError is an error given when the given type doesn't match an expected type

func (UnexpectedTypeError) Error

func (err UnexpectedTypeError) Error() string

type UnspecifiedCriteriaError

type UnspecifiedCriteriaError struct{}

func (UnspecifiedCriteriaError) Error

func (e UnspecifiedCriteriaError) Error() string

UnspecifiedCriteriaError is an error given when a Strategy cannot execute its criteria since it's left undefined

type UnspecifiedStrategyError

type UnspecifiedStrategyError struct{}

UnspecifiedStrategyError is an error given when a Strategy cannot be executed since it's defined Strategy parameter is null

func (UnspecifiedStrategyError) Error

func (e UnspecifiedStrategyError) Error() string

type UnsupportedCodeError

type UnsupportedCodeError struct {
	Code       string
	ColumnType string
}

UnsupportedCodeError is an error given when the code given by the template isn't supported by its type

func (UnsupportedCodeError) Error

func (e UnsupportedCodeError) Error() string

type UnsupportedTypeError

type UnsupportedTypeError struct {
	Type           string
	Code           string
	SupportedTypes []string
}

UnsupportedTypeError is an error given when the value given by the template doesn't match a supported type for that code

func (UnsupportedTypeError) Error

func (e UnsupportedTypeError) Error() string

type ValueStrategy

type ValueStrategy interface {
	Strategy
	SetValue(any)
}

func NewRandomDateStrategy

func NewRandomDateStrategy() ValueStrategy

NewRandomDateStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "RANDOM" for type "DATE"

func NewRandomFloatStrategy

func NewRandomFloatStrategy() ValueStrategy

func NewRandomIntStrategy

func NewRandomIntStrategy() ValueStrategy

NewRandomIntStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "RANDOM" for type "INT"

func NewRandomTimeStrategy

func NewRandomTimeStrategy() ValueStrategy

NewRandomTimeStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "RANDOM" for type "TIME"

func NewRegexStrategy

func NewRegexStrategy() ValueStrategy

NewRegexStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "REGEX" for type "VARCHAR"

func NewSerialStrategy

func NewSerialStrategy() ValueStrategy

NewSerialStrategy defines and returns a ValueStrategy of type SerialOptionalStrategy to handle the "SERIAL" code for the "INT" type

func NewStaticBoolStrategy

func NewStaticBoolStrategy() ValueStrategy

NewStaticBoolStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "STATIC" for type "BOOL"

func NewStaticDateStrategy

func NewStaticDateStrategy() ValueStrategy

NewStaticDateStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "STATIC" for type "DATE"

func NewStaticFloatStrategy

func NewStaticFloatStrategy() ValueStrategy

NewStaticFloatStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "STATIC" for type "FLOAT"

func NewStaticIntStrategy

func NewStaticIntStrategy() ValueStrategy

NewStaticIntStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "STATIC" for type "INT"

func NewStaticTimeStrategy

func NewStaticTimeStrategy() ValueStrategy

NewStaticTimeStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "STATIC" for type "TIME"

func NewStaticVarcharStrategy

func NewStaticVarcharStrategy() ValueStrategy

NewStaticVarcharStrategy defines and returns a Strategy of type RequiredStrategy meant to handle code "STATIC" for type "VARCHAR"

type ValueStrategyImplementedError

type ValueStrategyImplementedError struct {
}

ValueStrategyImplementedError is an error given when the user tries to add a ValueStrategy to the internal override map

func (ValueStrategyImplementedError) Error

Jump to

Keyboard shortcuts

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