drivers

package
v0.42.5 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package drivers talks to various database backends and retrieves table, column, type, and foreign key information

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClassifyPatterns

func ClassifyPatterns(patterns []string) (stringPatterns, regexPatterns []string)

func ColumnDBTypes

func ColumnDBTypes(cols []Column) map[string]string

ColumnDBTypes of the columns.

func ColumnNames

func ColumnNames(cols []Column) []string

ColumnNames of the columns.

func ColumnsFromList

func ColumnsFromList(list []string, tablename string) []string

ColumnsFromList takes a whitelist or blacklist and returns the columns for a given table.

func Skip

func Skip(name string, include, exclude []string) bool

Types

type AarondlNull

type AarondlNull struct{}

func (AarondlNull) NullType

func (a AarondlNull) NullType(name string) NullType

func (AarondlNull) NullTypeImports

func (a AarondlNull) NullTypeImports(forType Type) []string

func (AarondlNull) OptionalType

func (a AarondlNull) OptionalType(name string, def Type, isNull, fromOrToNull bool) (NullType, []string)

type AarondlNullPointers

type AarondlNullPointers struct{}

func (AarondlNullPointers) NullType

func (a AarondlNullPointers) NullType(name string) NullType

func (AarondlNullPointers) NullTypeImports

func (a AarondlNullPointers) NullTypeImports(forType Type) []string

func (AarondlNullPointers) OptionalType

func (a AarondlNullPointers) OptionalType(name string, def Type, isNull, fromOrToNull bool) (NullType, []string)

type Aliases

type Aliases map[string]TableAlias

Aliases defines aliases for the generation run

func (Aliases) Table

func (a Aliases) Table(table string) TableAlias

Table gets a table alias, panics if not found.

type Check

type Check[Extra any] struct {
	Constraint[Extra] `yaml:",squash" json:"-"`
	Expression        string `yaml:"expression" json:"expression"`
}

Check represents a check constraint in a database

func (Check[E]) MarshalJSON

func (c Check[E]) MarshalJSON() ([]byte, error)

func (*Check[E]) UnmarshalJSON

func (c *Check[E]) UnmarshalJSON(data []byte) error

type Column

type Column struct {
	Name      string `json:"name" yaml:"name"`
	DBType    string `json:"db_type" yaml:"db_type"`
	Default   string `json:"default" yaml:"default"`
	Comment   string `json:"comment" yaml:"comment"`
	Nullable  bool   `json:"nullable" yaml:"nullable"`
	Generated bool   `json:"generated" yaml:"generated"`
	AutoIncr  bool   `json:"autoincr" yaml:"autoincr"`

	// DomainName is the domain type name associated to the column. See here:
	// https://www.postgresql.org/docs/16/extend-type-system.html
	DomainName string `json:"domain_name" yaml:"domain_name"`

	Type       string   `json:"type" yaml:"type"`
	TypeLimits []string `json:"type_limits" yaml:"type_limits"`
}

Column holds information about a database column. Types are Go types, converted by TranslateColumnType.

func (Column) LimitsString

func (c Column) LimitsString() string

type ColumnFilter

type ColumnFilter map[string]Filter

func ParseColumnFilter

func ParseColumnFilter(tables []string, only, except map[string][]string) ColumnFilter

type Constraint

type Constraint[Extra any] struct {
	Name    string   `yaml:"name" json:"name"`
	Columns []string `yaml:"columns" json:"columns"`
	Comment string   `json:"comment" yaml:"comment"`
	Extra   Extra    `yaml:"extra" json:"extra"`
}

Constraint represents a constraint in a database

type Constraints

type Constraints[Extra any] struct {
	Primary *Constraint[Extra]  `yaml:"primary" json:"primary"`
	Foreign []ForeignKey[Extra] `yaml:"foreign" json:"foreign"`
	Uniques []Constraint[Extra] `yaml:"uniques" json:"uniques"`
	Checks  []Check[Extra]      `yaml:"check" json:"check"`
}

func (Constraints[E]) All

func (c Constraints[E]) All() []Constraint[E]

type Constructor

type Constructor[ConstraintExtra, IndexExtra any] interface {
	// Load basic info about all tables
	TablesInfo(context.Context, Filter) (TablesInfo, error)
	// Load details about a single table
	TableDetails(ctx context.Context, info TableInfo, filter ColumnFilter) (schema, name string, _ []Column, _ error)
	// Load all table comments, keyed by TableInfo.Key
	Comments(ctx context.Context) (map[string]string, error)
	// Load all constraints in the database, keyed by TableInfo.Key
	Constraints(context.Context, ColumnFilter) (DBConstraints[ConstraintExtra], error)
	// Load all indexes in the database, keyed by TableInfo.Key
	Indexes(ctx context.Context) (DBIndexes[IndexExtra], error)
}

Constructor breaks down the functionality required to implement a driver such that the drivers.Tables method can be used to reduce duplication in driver implementations.

type DBConstraints

type DBConstraints[Extra any] struct {
	PKs     map[string]*Constraint[Extra]
	FKs     map[string][]ForeignKey[Extra]
	Uniques map[string][]Constraint[Extra]
	Checks  map[string][]Check[Extra]
}

type DBIndexes

type DBIndexes[Extra any] map[string][]Index[Extra]

DBIndexes lists all indexes in the database schema keyed by table name

type DBInfo

type DBInfo[DBExtra, ConstraintExtra, IndexExtra any] struct {
	Tables       Tables[ConstraintExtra, IndexExtra] `json:"tables"`
	QueryFolders []QueryFolder                       `json:"query_folders"`
	Enums        []Enum                              `json:"enums"`
	ExtraInfo    DBExtra                             `json:"extra_info"`
	// Driver is the module name of the underlying `database/sql` driver
	Driver string `json:"driver"`
}

DBInfo is the database's table data and dialect.

type DatabaseSqlNull

type DatabaseSqlNull struct{}

func (DatabaseSqlNull) NullType

func (d DatabaseSqlNull) NullType(name string) NullType

func (DatabaseSqlNull) NullTypeImports

func (d DatabaseSqlNull) NullTypeImports(forType Type) []string

func (DatabaseSqlNull) OptionalType

func (d DatabaseSqlNull) OptionalType(name string, def Type, isNull, fromOrToNull bool) (NullType, []string)

type Enum

type Enum struct {
	Type   string
	Values []string
}

type Filter

type Filter struct {
	Only   []string
	Except []string
}

func ParseTableFilter

func ParseTableFilter(only, except map[string][]string) Filter

type ForeignKey

type ForeignKey[Extra any] struct {
	Constraint[Extra] `yaml:",squash" json:"-"`
	ForeignTable      string   `yaml:"foreign_table" json:"foreign_table"`
	ForeignColumns    []string `yaml:"foreign_columns" json:"foreign_columns"`
}

ForeignKey represents a foreign key constraint in a database

func (ForeignKey[E]) MarshalJSON

func (f ForeignKey[E]) MarshalJSON() ([]byte, error)

func (*ForeignKey[E]) UnmarshalJSON

func (f *ForeignKey[E]) UnmarshalJSON(data []byte) error

type Index

type Index[Extra any] struct {
	Type    string        `yaml:"type" json:"type"`
	Name    string        `yaml:"name" json:"name"`
	Columns []IndexColumn `yaml:"columns" json:"columns"`
	Unique  bool          `yaml:"unique" json:"unique"`
	Comment string        `json:"comment" yaml:"comment"`
	Extra   Extra         `yaml:"extra" json:"extra"`
}

Index represents an index in a table

func (Index[E]) HasExpressionColumn

func (i Index[E]) HasExpressionColumn() bool

func (Index[E]) NonExpressionColumns

func (i Index[E]) NonExpressionColumns() []string

type IndexColumn

type IndexColumn struct {
	Name         string         `yaml:"name" json:"name"`
	Desc         null.Val[bool] `yaml:"desc" json:"desc"`
	IsExpression bool           `yaml:"is_expression" json:"is_expression"`
}

type Interface

type Interface[DBExtra, ConstraintExtra, IndexExtra any] interface {
	// The dialect
	Dialect() string
	// Assemble the database information into a nice struct
	Assemble(ctx context.Context) (*DBInfo[DBExtra, ConstraintExtra, IndexExtra], error)
	// Custom types defined by the driver
	Types() Types
}

Interface abstracts either a side-effect imported driver or a binary that is called in order to produce the data required for generation.

type NullType

type NullType struct {
	// Name is the type to use for null values of this type
	Name string `yaml:"name"`
	// ValidExpr is used to check if a value of this type is valid
	// e.g. `SRC.Valid` for sql.Null[T] or `SRC.IsSet()` for null.Val[T]
	ValidExpr string `yaml:"valid_expr"`
	// UseExpr is used to convert a null value of this type
	// to a non-null value, if not provided it is assigned directly
	UseExpr string `yaml:"use_expr"`
	// Imports needed for the user expression
	UseExprImports []string `yaml:"use_expr_imports"`
	// CreateExpr is used to create a null value of this type
	// if not provided it is assigned directly
	CreateExpr string `yaml:"create_expr"`
	// Imports needed for the to null expression
	CreateExprImports []string `yaml:"create_expr_imports"`
}

type Query

type Query struct {
	Name   string        `json:"name"`
	SQL    string        `json:"raw"`
	Type   bob.QueryType `json:"type"`
	Config QueryConfig   `json:"config"`

	Columns QueryCols       `json:"columns"`
	Args    []QueryArg      `json:"args"`
	Mods    TemplateInclude `json:"mods"`
}

func (Query) ArgsByPosition

func (q Query) ArgsByPosition() []orm.ArgWithPosition

func (Query) HasMultipleArgs

func (q Query) HasMultipleArgs() bool

func (Query) HasNestedReturns

func (q Query) HasNestedReturns() bool

func (Query) HasNonMultipleArgs

func (q Query) HasNonMultipleArgs() bool

func (Query) MarshalJSON

func (q Query) MarshalJSON() ([]byte, error)

func (Query) NestedColumns

func (q Query) NestedColumns() nestedSlice

NestedColumns returns a list of nested columns in the query. Nesting is determined by the presence of a dot in the column's DBName. For example, if a column's DBName is "user.address.street", it will be nested under "user" and "address".

type QueryArg

type QueryArg struct {
	Col       QueryCol   `json:"col"`
	Children  []QueryArg `json:"children"`
	Positions [][2]int   `json:"positions"`

	CanBeMultiple bool `json:"can_be_multiple"`
}

func (QueryArg) RandomExpr

func (c QueryArg) RandomExpr(currPkg string, i language.Importer, types Types) string

func (QueryArg) ToExpression

func (a QueryArg) ToExpression(i language.Importer, dialect, queryName, varName string) string

func (QueryArg) Type

func (c QueryArg) Type(currPkg string, i language.Importer, types Types) string

func (QueryArg) TypeDef

func (c QueryArg) TypeDef(currPkg string, i language.Importer, types Types, doImport bool) string

func (QueryArg) Types

func (q QueryArg) Types() []string

type QueryCol

type QueryCol struct {
	Name       string   `json:"name"`
	DBName     string   `json:"db_name"`
	Nullable   *bool    `json:"nullable"`
	TypeName   string   `json:"type"`
	TypeLimits []string `json:"type_limits"`
}

func (QueryCol) Merge

func (q QueryCol) Merge(others ...QueryCol) QueryCol

func (QueryCol) Type

func (c QueryCol) Type(currPkg string, i language.Importer, types Types) string

func (QueryCol) TypeNoImport

func (c QueryCol) TypeNoImport(currPkg string, i language.Importer, types Types) string

type QueryCols

type QueryCols []QueryCol

func (QueryCols) NameAt

func (q QueryCols) NameAt(i int) string

func (QueryCols) WithNames

func (q QueryCols) WithNames() QueryCols

type QueryConfig

type QueryConfig struct {
	ResultTypeOne     string `json:"result_type_one"`
	ResultTypeAll     string `json:"result_type_all"`
	ResultTransformer string `json:"result_type_transformer"`
}

func (QueryConfig) Merge

func (q QueryConfig) Merge(other QueryConfig) QueryConfig

type QueryFile

type QueryFile struct {
	Path    string  `json:"path"`
	Queries []Query `json:"queries"`
}

func (QueryFile) BaseName

func (q QueryFile) BaseName() string

func (QueryFile) Formatted

func (q QueryFile) Formatted() string

func (QueryFile) QueryPosition

func (q QueryFile) QueryPosition(i, headerLen int) string

type QueryFolder

type QueryFolder struct {
	Path  string      `json:"path"`
	Files []QueryFile `json:"files"`
}

func (QueryFolder) Types

func (q QueryFolder) Types() []string

type Table

type Table[ConstraintExtra, IndexExtra any] struct {
	Key string `yaml:"key" json:"key"`
	// For dbs with real schemas, like Postgres.
	// Example value: "schema_name"."table_name"
	Schema      string                       `yaml:"schema" json:"schema"`
	Name        string                       `yaml:"name" json:"name"`
	Columns     []Column                     `yaml:"columns" json:"columns"`
	Indexes     []Index[IndexExtra]          `yaml:"indexes" json:"indexes"`
	Constraints Constraints[ConstraintExtra] `yaml:"constraints" json:"constraints"`
	Comment     string                       `json:"comment" yaml:"comment"`
}

Table metadata from the database schema.

func BuildDBInfo

func BuildDBInfo[DBExtra, ConstraintExtra, IndexExtra any](
	ctx context.Context, c Constructor[ConstraintExtra, IndexExtra],
	concurrency int, only, except map[string][]string,
) ([]Table[ConstraintExtra, IndexExtra], error)

This returns the metadata for all tables, minus the tables specified in the excludes.

func (Table[C, I]) CanSoftDelete

func (t Table[C, I]) CanSoftDelete(deleteColumn string) bool

func (Table[C, I]) DBTag

func (t Table[C, I]) DBTag(c Column) string

func (Table[C, I]) GetColumn

func (t Table[C, I]) GetColumn(name string) Column

GetColumn by name. Panics if not found (for use in templates mostly).

func (Table[C, I]) HasExactUnique

func (t Table[C, I]) HasExactUnique(cols ...string) bool

Returns true if the table has a unique constraint on exactly these columns

func (Table[C, I]) IsJoinTable

func (t Table[C, I]) IsJoinTable() bool

Used in templates to know if the given table is a join table for this relationship

func (Table[C, I]) IsJoinTableForRel

func (t Table[C, I]) IsJoinTableForRel(r orm.Relationship, position int) bool

Used in templates to know if the given table is a join table for this relationship

func (Table[C, I]) NonGeneratedColumns

func (t Table[C, I]) NonGeneratedColumns() []Column

func (Table[C, I]) RelIsRequired

func (t Table[C, I]) RelIsRequired(rel orm.Relationship) bool

func (Table[C, I]) UniqueColPairs

func (t Table[C, I]) UniqueColPairs() string

type TableAlias

type TableAlias struct {
	UpPlural     string `yaml:"up_plural,omitempty" json:"up_plural,omitempty"`
	UpSingular   string `yaml:"up_singular,omitempty" json:"up_singular,omitempty"`
	DownPlural   string `yaml:"down_plural,omitempty" json:"down_plural,omitempty"`
	DownSingular string `yaml:"down_singular,omitempty" json:"down_singular,omitempty"`

	Columns       map[string]string `yaml:"columns,omitempty" json:"columns,omitempty"`
	Relationships map[string]string `yaml:"relationships,omitempty" json:"relationships,omitempty"`
	Indexes       map[string]string `yaml:"indexes,omitempty" json:"indexes,omitempty"`
	Constraints   map[string]string `yaml:"constraints,omitempty" json:"constraints,omitempty"`
}

TableAlias defines the spellings for a table name in Go

func (TableAlias) Column

func (t TableAlias) Column(column string) string

Column get's a column's aliased name, panics if not found.

func (TableAlias) Constraint

func (t TableAlias) Constraint(constraint string) string

Constraint looks up a constraint, panics if not found.

func (TableAlias) Index

func (t TableAlias) Index(index string) string

Index looks up an index, panics if not found.

func (TableAlias) Relationship

func (t TableAlias) Relationship(fkey string) string

Relationship looks up a relationship, panics if not found.

type TableInfo

type TableInfo struct {
	Key     string
	Schema  string
	Name    string
	Comment string
}

type Tables

type Tables[C, I any] []Table[C, I]

func (Tables[C, I]) ColumnAssigner

func (tables Tables[C, I]) ColumnAssigner(
	currentPkg string, i language.Importer, types Types, aliases Aliases,
	destTName, srcTName string,
	destColName, srcColName string,
	varName string, destOpt bool,
) string

The source is never optional, but the destination can be

func (Tables[C, I]) ColumnGetter

func (tables Tables[C, I]) ColumnGetter(currPkg string, i language.Importer, types Types, table, column, varName string) string

func (Tables[C, I]) ColumnSetter

func (tables Tables[C, I]) ColumnSetter(currPkg string, i language.Importer, types Types, table, column, val, nullVal string) string

func (Tables[C, I]) Get

func (tables Tables[C, I]) Get(name string) Table[C, I]

GetTable by name. Panics if not found (for use in templates mostly).

func (Tables[C, I]) GetColumn

func (tables Tables[C, I]) GetColumn(table, column string) Column

func (Tables[C, I]) NeededBridgeRels

func (tables Tables[C, I]) NeededBridgeRels(r orm.Relationship) []struct {
	Table    string
	Position int
	Many     bool
}

func (Tables[C, I]) RelArgs

func (tables Tables[C, I]) RelArgs(aliases Aliases, r orm.Relationship) string

func (Tables[C, I]) RelDependencies

func (tables Tables[C, I]) RelDependencies(aliases Aliases, r orm.Relationship, preSuf ...string) string

func (Tables[C, I]) RelDependenciesPos

func (tables Tables[C, I]) RelDependenciesPos(aliases Aliases, r orm.Relationship) string

func (Tables[C, I]) RelDependenciesTyp

func (tables Tables[C, I]) RelDependenciesTyp(aliases Aliases, r orm.Relationship) string

func (Tables[C, I]) RelDependenciesTypSet

func (tables Tables[C, I]) RelDependenciesTypSet(aliases Aliases, r orm.Relationship) string

func (Tables[C, I]) RelIsView

func (tables Tables[C, I]) RelIsView(rel orm.Relationship) bool

func (Tables[C, I]) SetFactoryDeps

func (tables Tables[C, I]) SetFactoryDeps(currPkg string, i language.Importer, types Types, aliases Aliases, r orm.Relationship, inLoop bool) string

type TablesInfo

type TablesInfo []TableInfo

func (TablesInfo) Keys

func (t TablesInfo) Keys() []string

type TemplateInclude

type TemplateInclude interface {
	IncludeInTemplate(language.Importer) string
}

type Type

type Type struct {
	// If this type is an alias of another type
	// this is useful to have custom randomization for a type e.g. xml
	// NOTE: If an alias is set,
	// the only other relevant fields are RandomExpr and RandomExprImports
	AliasOf string `yaml:"alias_of"`
	// Imports needed for the type
	Imports []string `yaml:"imports"`
	// Any other types that this type depends on
	DependsOn []string `yaml:"depends_on"`
	// To be used in factory.random_type
	// Use BASETYPE to reference the name of the type
	// * A variable `f` of type `faker.Faker` is available
	// * Another variable `limits` which is a slice of strings with any limits
	//   for example, a VARCHAR(255) would have limits = ["255"]
	//   another example, a DECIMAL(10,2) would have limits = ["10", "2"]
	RandomExpr string `yaml:"random_expr"`
	// Additional imports for the randomize expression
	RandomExprImports []string `yaml:"random_expr_imports"`

	// CompareExpr is used to compare two values of this type
	// if not provided, == is used
	// Use AAA and BBB as placeholders for the two values
	CompareExpr string `yaml:"compare_expr"`
	// Imports needed for the compare expression
	CompareExprImports []string `yaml:"compare_expr_imports"`

	// NullType configures the type to use for null values of this type
	// if not provided, the type is wrapped in `sql.Null[T]`
	// the method of creating a null type can be customized
	NullType NullType `yaml:"null_type"`

	// Set this to true if the randomization should not be tested
	// this is useful for low-cardinality types like bool
	NoRandomizationTest bool `yaml:"no_randomization_test"`
	// Set this to true if the test to see if the type implements
	// the scanner and valuer interfaces should be skipped
	// this is useful for types that are based on a primitive type
	NoScannerValuerTest bool `yaml:"no_scanner_valuer_test"`
}

type TypeModifier

type TypeModifier interface {
	// NullType returns the type to use for null values of the given type
	NullType(string) NullType
	// NullTypeImport
	NullTypeImports(Type) []string
	// OptionalType returns the type to use for optional values of the given type
	// fromOrToNull may be used to modify the behaviour of the `UseExpr` and `CreateExpr`
	// When `fromOrToNull` is false
	// * the `UseExpr` should convert the optional value to a non-optional value
	// * the `CreateExpr` should convert a non-optional value to an optional value
	// When `fromOrToNull` is true
	// * the `UseExpr` should convert the optional value to a non-optional but nullable value
	// * the `CreateExpr` should convert a non-optional but nullable value to an optional value
	OptionalType(typName string, def Type, isNull, fromOrToNull bool) (NullType, []string)
}

type Types

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

func (Types) Contains

func (t Types) Contains(name string) bool

func (Types) FromOptional

func (t Types) FromOptional(currentPkg string, i language.Importer, forType, varName string, isNull, fromOrToNull bool) string

func (Types) Get

func (t Types) Get(curr string, i language.Importer, namedType string) string

func (Types) GetCompareExpr

func (t Types) GetCompareExpr(currentPkg string, i language.Importer, forType string, aNullable, bNullable bool) string

func (Types) GetNameAndDef

func (t Types) GetNameAndDef(curr, namedType string) (string, Type)

func (Types) GetNullType

func (t Types) GetNullType(currentPkg, forType string) NullType

func (Types) GetNullTypeValid

func (t Types) GetNullTypeValid(currentPkg, forType, varName string) string

func (Types) GetNullTypeWithImports

func (t Types) GetNullTypeWithImports(currentPkg, forType string) (NullType, []string)

func (Types) GetNullable

func (t Types) GetNullable(curr string, i language.Importer, namedType string, null bool) string

func (Types) GetOptional

func (t Types) GetOptional(curr string, i language.Importer, namedType string, null bool) NullType

func (Types) GetOptionalWithoutImporting

func (t Types) GetOptionalWithoutImporting(curr, namedType string, null bool) NullType

func (Types) GetWithoutImporting

func (t Types) GetWithoutImporting(curr, namedType string) string

func (Types) Index

func (t Types) Index(name string) Type

func (Types) IsOptionalValid

func (t Types) IsOptionalValid(currentPkg, forType string, null bool, varName string) string

func (*Types) Register

func (t *Types) Register(name string, typedef Type)

func (*Types) RegisterAll

func (t *Types) RegisterAll(m map[string]Type)

func (*Types) SetOutputImports

func (t *Types) SetOutputImports(pkgMap map[string]string)

func (*Types) SetTypeModifier

func (t *Types) SetTypeModifier(creator TypeModifier)

func (Types) ToOptional

func (t Types) ToOptional(currentPkg string, i language.Importer, forType, varName string, isNull, fromOrToNull bool) string

Jump to

Keyboard shortcuts

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