sqlgen

package
v10.3.1 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2024 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CommonTableSQLFragment = iota
	SelectSQLFragment
	SelectWithLimitSQLFragment
	FromSQLFragment
	JoinSQLFragment
	WhereSQLFragment
	GroupBySQLFragment
	HavingSQLFragment
	CompoundsSQLFragment
	OrderSQLFragment
	OrderWithOffsetFetchSQLFragment
	LimitSQLFragment
	OffsetSQLFragment
	ForSQLFragment
	UpdateBeginSQLFragment
	SourcesSQLFragment
	IntoSQLFragment
	UpdateSQLFragment
	UpdateFromSQLFragment
	ReturningSQLFragment
	InsertBeingSQLFragment
	InsertSQLFragment
	DeleteBeginSQLFragment
	TruncateSQLFragment
	WindowSQLFragment
)

Variables

View Source
var (
	TrueLiteral  = exp.NewLiteralExpression("TRUE")
	FalseLiteral = exp.NewLiteralExpression("FALSE")

	ErrEmptyIdentifier = errors.New(
		`a empty identifier was encountered, please specify a "schema", "table" or "column"`,
	)
	ErrUnexpectedNamedWindow = errors.New(`unexpected named window function`)
	ErrEmptyCaseWhens        = errors.New(`when conditions not found for case statement`)
)
View Source
var (
	ErrConflictUpdateValuesRequired = errors.New("values are required for on conflict update expression")
	ErrNoSourceForInsert            = errors.New("no source found when generating insert sql")
)
View Source
var (
	ErrNoSourceForUpdate    = errors.New("no source found when generating update sql")
	ErrNoSetValuesForUpdate = errors.New("no set values found when generating UPDATE sql")
)
View Source
var ErrNoSourceForDelete = errors.New("no source found when generating delete sql")
View Source
var ErrNoUpdatedValuesProvided = errors.New("no update values provided")
View Source
var ErrNoWindowName = errors.New("window expresion has no valid name")

Functions

func ErrCTENotSupported

func ErrCTENotSupported(dialect string) error

func ErrDistinctOnNotSupported

func ErrDistinctOnNotSupported(dialect string) error

func ErrJoinConditionRequired

func ErrJoinConditionRequired(j exp.JoinExpression) error

func ErrNotSupportedFragment

func ErrNotSupportedFragment(sqlType string, f SQLFragmentType) error

func ErrNotSupportedJoinType

func ErrNotSupportedJoinType(j exp.JoinExpression) error

func ErrRecursiveCTENotSupported

func ErrRecursiveCTENotSupported(dialect string) error

func ErrReturnNotSupported

func ErrReturnNotSupported(dialect string) error

func ErrWindowNotSupported

func ErrWindowNotSupported(dialect string) error

func GenerateExpressionSQL

func GenerateExpressionSQL(esg ExpressionSQLGenerator, isPrepared bool, val interface{}) (sql string, args []interface{}, err error)

func GetTimeLocation

func GetTimeLocation() *time.Location

func SetTimeLocation

func SetTimeLocation(loc *time.Location)

Set the location to use when interpolating time.Time instances. See https://golang.org/pkg/time/#LoadLocation NOTE: This has no effect when using prepared statements.

Types

type CommonSQLGenerator

type CommonSQLGenerator interface {
	Dialect() string
	DialectOptions() *SQLDialectOptions
	ExpressionSQLGenerator() ExpressionSQLGenerator
	ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression)
	FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
	SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
	WhereSQL(b sb.SQLBuilder, where exp.ExpressionList)
	OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression)
	OrderWithOffsetFetchSQL(b sb.SQLBuilder, order exp.ColumnListExpression, offset uint, limit interface{})
	LimitSQL(b sb.SQLBuilder, limit interface{})
	UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression)
}

func NewCommonSQLGenerator

func NewCommonSQLGenerator(dialect string, do *SQLDialectOptions) CommonSQLGenerator

type DeleteSQLGenerator

type DeleteSQLGenerator interface {
	Dialect() string
	Generate(b sb.SQLBuilder, clauses exp.DeleteClauses)
}

An adapter interface to be used by a Dataset to generate SQL for a specific dialect. See DefaultAdapter for a concrete implementation and examples.

func NewDeleteSQLGenerator

func NewDeleteSQLGenerator(dialect string, do *SQLDialectOptions) DeleteSQLGenerator

type ExpressionSQLGenerator

type ExpressionSQLGenerator interface {
	Dialect() string
	Generate(b sb.SQLBuilder, val interface{})
}

An adapter interface to be used by a Dataset to generate SQL for a specific dialect. See DefaultAdapter for a concrete implementation and examples.

func NewExpressionSQLGenerator

func NewExpressionSQLGenerator(dialect string, do *SQLDialectOptions) ExpressionSQLGenerator

type InsertSQLGenerator

type InsertSQLGenerator interface {
	Dialect() string
	Generate(b sb.SQLBuilder, clauses exp.InsertClauses)
}

An adapter interface to be used by a Dataset to generate SQL for a specific dialect. See DefaultAdapter for a concrete implementation and examples.

func NewInsertSQLGenerator

func NewInsertSQLGenerator(dialect string, do *SQLDialectOptions) InsertSQLGenerator

type SQLDialectOptions

type SQLDialectOptions struct {
	// Set to true if the dialect supports ORDER BY expressions in DELETE statements (DEFAULT=false)
	SupportsOrderByOnDelete bool
	// Set to true if the dialect supports table hint for DELETE statements (DELETE t FROM t ...), DEFAULT=false
	SupportsDeleteTableHint bool
	// Set to true if the dialect supports ORDER BY expressions in UPDATE statements (DEFAULT=false)
	SupportsOrderByOnUpdate bool
	// Set to true if the dialect supports LIMIT expressions in DELETE statements (DEFAULT=false)
	SupportsLimitOnDelete bool
	// Set to true if the dialect supports LIMIT expressions in UPDATE statements (DEFAULT=false)
	SupportsLimitOnUpdate bool
	// Set to true if the dialect supports RETURN expressions (DEFAULT=true)
	SupportsReturn bool
	// Set to true if the dialect supports Conflict Target (DEFAULT=true)
	SupportsConflictTarget bool
	// Set to true if the dialect supports Conflict Target (DEFAULT=true)
	SupportsConflictUpdateWhere bool
	// Set to true if the dialect supports Insert Ignore syntax (DEFAULT=false)
	SupportsInsertIgnoreSyntax bool
	// Set to true if the dialect supports Common Table Expressions (DEFAULT=true)
	SupportsWithCTE bool
	// Set to true if the dialect supports recursive Common Table Expressions (DEFAULT=true)
	SupportsWithCTERecursive bool
	// Set to true if multiple tables are supported in UPDATE statement. (DEFAULT=true)
	SupportsMultipleUpdateTables bool
	// Set to true if DISTINCT ON is supported (DEFAULT=true)
	SupportsDistinctOn bool
	// Set to true if LATERAL queries are supported (DEFAULT=true)
	SupportsLateral bool
	// Set to false if the dialect does not require expressions to be wrapped in parens (DEFAULT=true)
	WrapCompoundsInParens bool

	// Set to true if window function are supported in SELECT statement. (DEFAULT=true)
	SupportsWindowFunction bool

	// Set to true if the dialect requires join tables in UPDATE to be in a FROM clause (DEFAULT=true).
	UseFromClauseForMultipleUpdateTables bool

	// Surround LIMIT parameter with parentheses, like in MSSQL: SELECT TOP (10) ...
	SurroundLimitWithParentheses bool

	// The UPDATE fragment to use when generating sql. (DEFAULT=[]byte("UPDATE"))
	UpdateClause []byte
	// The INSERT fragment to use when generating sql. (DEFAULT=[]byte("INSERT INTO"))
	InsertClause []byte
	// The INSERT IGNORE INTO fragment to use when generating sql. (DEFAULT=[]byte("INSERT IGNORE INTO"))
	InsertIgnoreClause []byte
	// The SELECT fragment to use when generating sql. (DEFAULT=[]byte("SELECT"))
	SelectClause []byte
	// The DELETE fragment to use when generating sql. (DEFAULT=[]byte("DELETE"))
	DeleteClause []byte
	// The TRUNCATE fragment to use when generating sql. (DEFAULT=[]byte("TRUNCATE"))
	TruncateClause []byte
	// The WITH fragment to use when generating sql. (DEFAULT=[]byte("WITH "))
	WithFragment []byte
	// The RECURSIVE fragment to use when generating sql (after WITH). (DEFAULT=[]byte("RECURSIVE "))
	RecursiveFragment []byte
	// The CASCADE fragment to use when generating sql. (DEFAULT=[]byte(" CASCADE"))
	CascadeFragment []byte
	// The RESTRICT fragment to use when generating sql. (DEFAULT=[]byte(" RESTRICT"))
	RestrictFragment []byte
	// The SQL fragment to use when generating insert sql and using
	// DEFAULT VALUES (e.g. postgres="DEFAULT VALUES", mysql="", sqlite3=""). (DEFAULT=[]byte(" DEFAULT VALUES"))
	DefaultValuesFragment []byte
	// The SQL fragment to use when generating insert sql and listing columns using a VALUES clause
	// (DEFAULT=[]byte(" VALUES "))
	ValuesFragment []byte
	// The SQL fragment to use when generating truncate sql and using the IDENTITY clause
	// (DEFAULT=[]byte(" IDENTITY"))
	IdentityFragment []byte
	// The SQL fragment to use when generating update sql and using the SET clause (DEFAULT=[]byte(" SET "))
	SetFragment []byte
	// The SQL DISTINCT keyword (DEFAULT=[]byte(" DISTINCT "))
	DistinctFragment []byte
	// The SQL RETURNING clause (DEFAULT=[]byte(" RETURNING "))
	ReturningFragment []byte
	// The SQL FROM clause fragment (DEFAULT=[]byte(" FROM"))
	FromFragment []byte
	// The SQL USING join clause fragment (DEFAULT=[]byte(" USING "))
	UsingFragment []byte
	// The SQL ON join clause fragment (DEFAULT=[]byte(" ON "))
	OnFragment []byte
	// The SQL WHERE clause fragment (DEFAULT=[]byte(" WHERE "))
	WhereFragment []byte
	// The SQL GROUP BY clause fragment(DEFAULT=[]byte(" GROUP BY "))
	GroupByFragment []byte
	// The SQL HAVING clause fragment(DEFAULT=[]byte(" HAVING "))
	HavingFragment []byte
	// The SQL WINDOW clause fragment(DEFAULT=[]byte(" WINDOW "))
	WindowFragment []byte
	// The SQL WINDOW clause PARTITION BY fragment(DEFAULT=[]byte("PARTITION BY "))
	WindowPartitionByFragment []byte
	// The SQL WINDOW clause ORDER BY fragment(DEFAULT=[]byte("ORDER BY "))
	WindowOrderByFragment []byte
	// The SQL WINDOW clause OVER fragment(DEFAULT=[]byte(" OVER "))
	WindowOverFragment []byte
	// The SQL ORDER BY clause fragment(DEFAULT=[]byte(" ORDER BY "))
	OrderByFragment []byte
	// The SQL FETCH fragment(DEFAULT=[]byte(" "))
	FetchFragment []byte
	// The SQL LIMIT BY clause fragment(DEFAULT=[]byte(" LIMIT "))
	LimitFragment []byte
	// The SQL OFFSET BY clause fragment(DEFAULT=[]byte(" OFFSET "))
	OffsetFragment []byte
	// The SQL FOR UPDATE fragment(DEFAULT=[]byte(" FOR UPDATE "))
	ForUpdateFragment []byte
	// The SQL FOR NO KEY UPDATE fragment(DEFAULT=[]byte(" FOR NO KEY UPDATE "))
	ForNoKeyUpdateFragment []byte
	// The SQL FOR SHARE fragment(DEFAULT=[]byte(" FOR SHARE "))
	ForShareFragment []byte
	// The SQL OF fragment(DEFAULT=[]byte("OF "))
	OfFragment []byte
	// The SQL FOR KEY SHARE fragment(DEFAULT=[]byte(" FOR KEY SHARE "))
	ForKeyShareFragment []byte
	// The SQL NOWAIT fragment(DEFAULT=[]byte("NOWAIT"))
	NowaitFragment []byte
	// The SQL SKIP LOCKED fragment(DEFAULT=[]byte("SKIP LOCKED"))
	SkipLockedFragment []byte
	// The SQL AS fragment when aliasing an Expression(DEFAULT=[]byte(" AS "))
	AsFragment []byte
	// The SQL LATERAL fragment used for LATERAL joins
	LateralFragment []byte
	// Whether or not to quote identifiers (DEFAULT=true)
	QuoteIdentifiers bool
	// The quote rune to use when quoting identifiers(DEFAULT='"')
	QuoteRune rune
	// The NULL literal to use when interpolating nulls values (DEFAULT=[]byte("NULL"))
	Null []byte
	// The TRUE literal to use when interpolating bool true values (DEFAULT=[]byte("TRUE"))
	True []byte
	// The FALSE literal to use when interpolating bool false values (DEFAULT=[]byte("FALSE"))
	False []byte
	// The ASC fragment when specifying column order (DEFAULT=[]byte(" ASC"))
	AscFragment []byte
	// The DESC fragment when specifying column order (DEFAULT=[]byte(" DESC"))
	DescFragment []byte
	// The NULLS FIRST fragment when specifying column order (DEFAULT=[]byte(" NULLS FIRST"))
	NullsFirstFragment []byte
	// The NULLS LAST fragment when specifying column order (DEFAULT=[]byte(" NULLS LAST"))
	NullsLastFragment []byte
	// The AND keyword used when joining ExpressionLists (DEFAULT=[]byte(" AND "))
	AndFragment []byte
	// The OR keyword used when joining ExpressionLists (DEFAULT=[]byte(" OR "))
	OrFragment []byte
	// The UNION keyword used when creating compound statements (DEFAULT=[]byte(" UNION "))
	UnionFragment []byte
	// The UNION ALL keyword used when creating compound statements (DEFAULT=[]byte(" UNION ALL "))
	UnionAllFragment []byte
	// The INTERSECT keyword used when creating compound statements (DEFAULT=[]byte(" INTERSECT "))
	IntersectFragment []byte
	// The INTERSECT ALL keyword used when creating compound statements (DEFAULT=[]byte(" INTERSECT ALL "))
	IntersectAllFragment []byte
	// The CAST keyword to use when casting a value (DEFAULT=[]byte("CAST"))
	CastFragment []byte
	// The CASE keyword to use when when creating a CASE statement (DEFAULT=[]byte("CASE "))
	CaseFragment []byte
	// The WHEN keyword to use when when creating a CASE statement (DEFAULT=[]byte(" WHEN "))
	WhenFragment []byte
	// The THEN keyword to use when when creating a CASE statement (DEFAULT=[]byte(" THEN "))
	ThenFragment []byte
	// The ELSE keyword to use when when creating a CASE statement (DEFAULT=[]byte(" ELSE "))
	ElseFragment []byte
	// The End keyword to use when when creating a CASE statement (DEFAULT=[]byte(" END"))
	EndFragment []byte
	// The quote rune to use when quoting string literals (DEFAULT='\”)
	StringQuote rune
	// The operator to use when setting values in an update statement (DEFAULT='=')
	SetOperatorRune rune
	// The placeholder fragment to use when generating a non interpolated statement (DEFAULT=[]byte"?")
	PlaceHolderFragment []byte
	// Empty string (DEFAULT="")
	EmptyString string
	// Comma rune (DEFAULT=',')
	CommaRune rune
	// Space rune (DEFAULT=' ')
	SpaceRune rune
	// Left paren rune (DEFAULT='(')
	LeftParenRune rune
	// Right paren rune (DEFAULT=')')
	RightParenRune rune
	// Star rune (DEFAULT='*')
	StarRune rune
	// Period rune (DEFAULT='.')
	PeriodRune rune
	// Set to true to include positional argument numbers when creating a prepared statement (Default=false)
	IncludePlaceholderNum bool
	// The literal value to wrap timestamps with when interpolating time.Time, e.g. from_iso8601_timestamp(?) (DEFAULT="")
	TimeFunctionLiteral string
	// The time format to use when serializing time.Time (DEFAULT=time.RFC3339Nano)
	TimeFormat string
	// A map used to look up BooleanOperations and their SQL equivalents
	// (Default= map[exp.BooleanOperation][]byte{
	// 		exp.EqOp:             []byte("="),
	// 		exp.NeqOp:            []byte("!="),
	// 		exp.GtOp:             []byte(">"),
	// 		exp.GteOp:            []byte(">="),
	// 		exp.LtOp:             []byte("<"),
	// 		exp.LteOp:            []byte("<="),
	// 		exp.InOp:             []byte("IN"),
	// 		exp.NotInOp:          []byte("NOT IN"),
	// 		exp.IsOp:             []byte("IS"),
	// 		exp.IsNotOp:          []byte("IS NOT"),
	// 		exp.LikeOp:           []byte("LIKE"),
	// 		exp.NotLikeOp:        []byte("NOT LIKE"),
	// 		exp.ILikeOp:          []byte("ILIKE"),
	// 		exp.NotILikeOp:       []byte("NOT ILIKE"),
	// 		exp.RegexpLikeOp:     []byte("~"),
	// 		exp.RegexpNotLikeOp:  []byte("!~"),
	// 		exp.RegexpILikeOp:    []byte("~*"),
	// 		exp.RegexpNotILikeOp: []byte("!~*"),
	// })
	BooleanOperatorLookup map[exp.BooleanOperation][]byte
	// A map used to look up BitwiseOperations and their SQL equivalents
	// (Default=map[exp.BitwiseOperation][]byte{
	// 		exp.BitwiseInversionOp:  []byte("~"),
	// 		exp.BitwiseOrOp:         []byte("|"),
	// 		exp.BitwiseAndOp:        []byte("&"),
	// 		exp.BitwiseXorOp:        []byte("#"),
	// 		exp.BitwiseLeftShiftOp:  []byte("<<"),
	// 		exp.BitwiseRightShiftOp: []byte(">>"),
	// }),
	BitwiseOperatorLookup map[exp.BitwiseOperation][]byte
	// A map used to look up RangeOperations and their SQL equivalents
	// (Default=map[exp.RangeOperation][]byte{
	// 		exp.BetweenOp:    []byte("BETWEEN"),
	// 		exp.NotBetweenOp: []byte("NOT BETWEEN"),
	// 	})
	RangeOperatorLookup map[exp.RangeOperation][]byte
	// A map used to look up JoinTypes and their SQL equivalents
	// (Default= map[exp.JoinType][]byte{
	// 		exp.InnerJoinType:        []byte(" INNER JOIN "),
	// 		exp.FullOuterJoinType:    []byte(" FULL OUTER JOIN "),
	// 		exp.RightOuterJoinType:   []byte(" RIGHT OUTER JOIN "),
	// 		exp.LeftOuterJoinType:    []byte(" LEFT OUTER JOIN "),
	// 		exp.FullJoinType:         []byte(" FULL JOIN "),
	// 		exp.RightJoinType:        []byte(" RIGHT JOIN "),
	// 		exp.LeftJoinType:         []byte(" LEFT JOIN "),
	// 		exp.NaturalJoinType:      []byte(" NATURAL JOIN "),
	// 		exp.NaturalLeftJoinType:  []byte(" NATURAL LEFT JOIN "),
	// 		exp.NaturalRightJoinType: []byte(" NATURAL RIGHT JOIN "),
	// 		exp.NaturalFullJoinType:  []byte(" NATURAL FULL JOIN "),
	// 		exp.CrossJoinType:        []byte(" CROSS JOIN "),
	// 	})
	JoinTypeLookup map[exp.JoinType][]byte
	// Whether or not to use Eq operator for boolean data types instead of Is (DEFAULT=false)
	UseEqForBooleanDataTypes bool
	// Whether or not boolean data type is supported
	BooleanDataTypeSupported bool
	// Whether or not to use literal TRUE or FALSE for IS statements (e.g. IS TRUE or IS 0)
	UseLiteralIsBools bool
	// EscapedRunes is a map of a rune and the corresponding escape sequence in bytes. Used when escaping text
	// types.
	// (Default= map[rune][]byte{
	// 		'\”: []byte("”"),
	// 	})
	EscapedRunes map[rune][]byte

	// The SQL fragment to use for CONFLICT (Default=[]byte(" ON CONFLICT"))
	ConflictFragment []byte
	// The SQL fragment to use for CONFLICT DO NOTHING (Default=[]byte(" DO NOTHING"))
	ConflictDoNothingFragment []byte
	// The SQL fragment to use for CONFLICT DO UPDATE (Default=[]byte(" DO UPDATE SET"))
	ConflictDoUpdateFragment []byte

	// The order of SQL fragments when creating a SELECT statement
	// (Default=[]SQLFragmentType{
	// 		CommonTableSQLFragment,
	// 		SelectSQLFragment,
	// 		FromSQLFragment,
	// 		JoinSQLFragment,
	// 		WhereSQLFragment,
	// 		GroupBySQLFragment,
	// 		HavingSQLFragment,
	// 		CompoundsSQLFragment,
	// 		OrderSQLFragment,
	// 		LimitSQLFragment,
	// 		OffsetSQLFragment,
	// 		ForSQLFragment,
	// 	})
	SelectSQLOrder []SQLFragmentType

	// The order of SQL fragments when creating an UPDATE statement
	// (Default=[]SQLFragmentType{
	// 		CommonTableSQLFragment,
	// 		UpdateBeginSQLFragment,
	// 		SourcesSQLFragment,
	// 		UpdateSQLFragment,
	// 		WhereSQLFragment,
	// 		OrderSQLFragment,
	// 		LimitSQLFragment,
	// 		ReturningSQLFragment,
	// 	})
	UpdateSQLOrder []SQLFragmentType

	// The order of SQL fragments when creating an INSERT statement
	// (Default=[]SQLFragmentType{
	// 		CommonTableSQLFragment,
	// 		InsertBeingSQLFragment,
	// 		SourcesSQLFragment,
	// 		InsertSQLFragment,
	// 		ReturningSQLFragment,
	// 	})
	InsertSQLOrder []SQLFragmentType

	// The order of SQL fragments when creating a DELETE statement
	// (Default=[]SQLFragmentType{
	// 		CommonTableSQLFragment,
	// 		DeleteBeginSQLFragment,
	// 		FromSQLFragment,
	// 		WhereSQLFragment,
	// 		OrderSQLFragment,
	// 		LimitSQLFragment,
	// 		ReturningSQLFragment,
	// 	})
	DeleteSQLOrder []SQLFragmentType

	// The order of SQL fragments when creating a TRUNCATE statement
	// (Default=[]SQLFragmentType{
	// 		TruncateSQLFragment,
	// 	})
	TruncateSQLOrder []SQLFragmentType
}

func DefaultDialectOptions

func DefaultDialectOptions() *SQLDialectOptions

func (*SQLDialectOptions) QuoteRunes

func (o *SQLDialectOptions) QuoteRunes() []rune

type SQLFragmentType

type SQLFragmentType int

func (SQLFragmentType) String

func (sf SQLFragmentType) String() string

type SelectSQLGenerator

type SelectSQLGenerator interface {
	Dialect() string
	Generate(b sb.SQLBuilder, clauses exp.SelectClauses)
}

An adapter interface to be used by a Dataset to generate SQL for a specific dialect. See DefaultAdapter for a concrete implementation and examples.

func NewSelectSQLGenerator

func NewSelectSQLGenerator(dialect string, do *SQLDialectOptions) SelectSQLGenerator

type TruncateSQLGenerator

type TruncateSQLGenerator interface {
	Dialect() string
	Generate(b sb.SQLBuilder, clauses exp.TruncateClauses)
}

An adapter interface to be used by a Dataset to generate SQL for a specific dialect. See DefaultAdapter for a concrete implementation and examples.

func NewTruncateSQLGenerator

func NewTruncateSQLGenerator(dialect string, do *SQLDialectOptions) TruncateSQLGenerator

type UpdateSQLGenerator

type UpdateSQLGenerator interface {
	Dialect() string
	Generate(b sb.SQLBuilder, clauses exp.UpdateClauses)
}

An adapter interface to be used by a Dataset to generate SQL for a specific dialect. See DefaultAdapter for a concrete implementation and examples.

func NewUpdateSQLGenerator

func NewUpdateSQLGenerator(dialect string, do *SQLDialectOptions) UpdateSQLGenerator

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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