Documentation
¶
Overview ¶
Package parser provides multi-dialect SQL parsing, schema model types, and relationship detection for SQLGen code generation.
Index ¶
- func ApplyConstraintToColumns(table *Table, c Constraint)
- func ApplyTableConstraints(table *Table)
- func CheckTableDropRefs(tables []Table, schema, name string) error
- func CheckTypeDropRefs(tables []Table, schema, name string) error
- func DetectRelationships(schema *Schema)
- func DetectSoftDelete(table *Table, columns []string) (column string, strategy string, err error)
- func DetectUpdateColumns(table *Table, names []string) []string
- func DiscoverFiles(paths []string) ([]string, error)
- func IsAggregateFunction(funcName string) bool
- func MoveTableReferences(tables []Table, name, oldSchema, newSchema string)
- func ParseFiles(p Parser, files []string) error
- func RecomputeColumnUnique(table *Table, colName string)
- func RenameColumn(table *Table, oldName, newName string) error
- func RenameColumnReferences(tables []Table, schema, table, oldName, newName string)
- func RenameTableReferences(tables []Table, schema, oldName, newName string)
- func UnresolvedForeignKeys(tables []Table) []error
- type Attribute
- type Column
- type CompositeType
- type Constraint
- type ConstraintType
- type DomainType
- type Enum
- type FKReference
- type Parser
- type Relationship
- type RelationshipSide
- type RelationshipSort
- type RelationshipType
- type Schema
- type Set
- type Table
- type View
- type ViewAnnotations
- type ViewSQL
- type ViewSelectColumn
- type ViewTypeAnnotation
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyConstraintToColumns ¶
func ApplyConstraintToColumns(table *Table, c Constraint)
ApplyConstraintToColumns updates column flags from a single constraint.
func ApplyTableConstraints ¶
func ApplyTableConstraints(table *Table)
ApplyTableConstraints propagates table-level constraint metadata to columns.
func CheckTableDropRefs ¶
CheckTableDropRefs checks whether any table in the schema has a foreign key reference to the table identified by (schema, name). Returns an error describing the first dangling reference found, or nil if the drop is safe.
func CheckTypeDropRefs ¶
CheckTypeDropRefs checks whether any column in the schema uses the given type name. Returns an error if a reference is found, or nil if the drop is safe.
func DetectRelationships ¶
func DetectRelationships(schema *Schema)
DetectRelationships detects relationships from foreign key constraints in the schema. It identifies Many-to-Many (junction tables with exactly 2 FKs in a composite PK/UNIQUE), One-to-One (FK column with UNIQUE), and One-to-Many (FK column without UNIQUE, the default fallback). Detected relationships are appended to schema.Relationships.
func DetectSoftDelete ¶
DetectSoftDelete checks the table's columns against the given column names in priority order. The first matching column determines the soft delete column. The strategy is inferred from the column's SQL type: "timestamp" for timestamp/timestamptz/datetime, "bool" for bool/boolean, "integer" for int/integer/smallint/tinyint. Returns empty strings if no column matches. Returns an error if a matching column has an unsupported type.
func DetectUpdateColumns ¶
DetectUpdateColumns finds columns in the table that match the given column names. Returns matching column names in the order they appear in the names list.
func DiscoverFiles ¶
DiscoverFiles resolves a list of paths into an ordered list of SQL files suitable for parsing. Each path may be a file or a directory. Directories are expanded to their contained .sql files in lexicographic order. Down-migration files (*.down.sql, *_down.sql) are automatically excluded. Paths are processed in the order specified; ordering within a directory is lexicographic.
func IsAggregateFunction ¶
IsAggregateFunction returns true if funcName (uppercase) is a known SQL aggregate function. Dialect parsers use this when classifying SELECT expressions.
func MoveTableReferences ¶
MoveTableReferences repoints every foreign key that references the table (oldSchema, name) at (newSchema, name), so an ALTER TABLE … SET SCHEMA keeps the keys that reference the table resolvable.
func ParseFiles ¶
ParseFiles parses multiple SQL files sequentially, applying each file's statements to the parser's accumulating schema. Files are processed in the order provided (use DiscoverFiles to resolve paths).
Each file's DDL is applied as a natural SQL migration: ALTER TABLE extends or modifies tables, DROP TABLE removes tables, and so on. Duplicate CREATE statements (table, enum, composite type, domain type) are validation errors — each schema element must be defined exactly once.
func RecomputeColumnUnique ¶
RecomputeColumnUnique re-derives the column's Unique flag from the current table state — the column's InlineUnique flag plus any unconditional, single-column UNIQUE constraint remaining in table.Constraints. Callers must remove the dropped constraint from table.Constraints before invoking this helper; partial UNIQUE constraints (Where != "") are ignored because they cannot keep the column unconditionally unique.
func RenameColumn ¶
RenameColumn renames a column in the table from oldName to newName.
func RenameColumnReferences ¶
RenameColumnReferences rewrites every reference to column oldName of the table (schema, table) to newName: the column lists of that table's own constraints (PRIMARY KEY, UNIQUE, FOREIGN KEY, INDEX, CHECK), and every foreign key, on any table, that references the column. The database does the same on RENAME COLUMN; left on the old name, a composite key no longer matches its columns, so an M2M junction degrades to O2M and an upsert conflict target names a column that no longer exists. Call it after RenameColumn has renamed the column itself.
func RenameTableReferences ¶
RenameTableReferences repoints every foreign key that references the table (schema, oldName) at (schema, newName), so a RENAME TABLE keeps the keys that reference the table resolvable.
func UnresolvedForeignKeys ¶
UnresolvedForeignKeys returns one error per foreign key whose referenced table is not in tables, sorted for deterministic output. Relationship detection builds an edge from every foreign key, and an edge whose far end was never parsed is dropped without a trace, so the caller reports these instead.
Types ¶
type Column ¶
type Column struct {
Name string
Type string
Nullable bool
PrimaryKey bool
Unique bool
// InlineUnique reports whether the column carries a UNIQUE constraint
// declared inline at column definition time (e.g. `email text UNIQUE`),
// as opposed to a table-level UNIQUE constraint that lives in
// Table.Constraints. The DDL parsers set this alongside Unique at column
// parse time; RecomputeColumnUnique consults it when re-deriving the
// effective Unique flag after a table-level UNIQUE is dropped, so an
// inline declaration still in force at the DB level is not silently
// stripped from the column.
InlineUnique bool
Default string
FKReference *FKReference
AutoIncrement bool
Comment string
GeneratedExpr string // Generated column expression (SQLite 3.31+)
GeneratedStorage string // "VIRTUAL" or "STORED" (default: "VIRTUAL")
// GoTypeLiteral is set for view columns whose type was resolved to a Go type
// by @type annotation or aggregate inference. When non-empty, the code generator
// uses this directly instead of running the SQL-to-Go resolver.
GoTypeLiteral string
// GoTypeImport is the import path for an external Go type (from @type annotation).
GoTypeImport string
// Aggregate names the SQL aggregate function (uppercase, e.g. "SUM") when this
// view column is an aggregate whose Go type flows through the SQL-to-Go
// resolver rather than a Go-type literal. Empty for table columns and for
// aggregates resolved to a literal. The generator consults it so the
// resolver can model dialect-specific result widening (e.g. SUM(integer) →
// bigint in PostgreSQL); see gotype.Resolver.ResolveAggregate.
Aggregate string
}
Column represents a column in a table.
func ColumnByName ¶
ColumnByName returns a pointer to the named column in the table, or nil.
type CompositeType ¶
CompositeType represents a named struct-like type with attributes.
type Constraint ¶
type Constraint struct {
Name string
Type ConstraintType
Columns []string
ReferenceTable string
ReferenceSchema string
ReferenceColumns []string
CheckExpression string
Method string
Where string
}
Constraint represents a table-level constraint.
Method and Where apply only to index-shaped constraints (Index and Unique). Method holds the access-method name when the DDL declares one — "btree", "gin", "gist", "hash", and so on — and is empty otherwise; consumers that need a default treat the empty string as "btree" (PostgreSQL's default). Where holds the predicate text of a partial index (PostgreSQL / SQLite) without the leading WHERE keyword; MySQL does not support partial indexes so Where stays empty for that dialect.
type ConstraintType ¶
type ConstraintType int
ConstraintType represents the kind of a table constraint.
const ( // PrimaryKey is a PRIMARY KEY constraint. PrimaryKey ConstraintType = iota + 1 // ForeignKey is a FOREIGN KEY constraint. ForeignKey // Unique is a UNIQUE constraint. Unique // Check is a CHECK constraint. Check // Index is an INDEX constraint. Index )
func (ConstraintType) String ¶
func (ct ConstraintType) String() string
String returns the string representation of the constraint type.
type DomainType ¶
type DomainType struct {
Name string
Schema string
BaseType string
Constraints []Constraint
Comment string
}
DomainType represents a named alias type with optional constraints.
type FKReference ¶
type FKReference struct {
Table string
Schema string
Column string
// Synthetic marks a reference invented by a config-declared relationship
// (gen.applyConfigDeclaredFKs) rather than read from a SQL REFERENCES
// clause. The database does not enforce it, and it may name a column that
// holds no foreign key at all, so any consumer deciding something about
// the *referential contract* — as opposed to how a column is filtered or
// typed — must exclude it. Column is empty for synthetic references, but
// that is not a usable test: the MySQL and SQLite parsers also leave it
// empty when a REFERENCES clause omits the referenced column list.
Synthetic bool
}
FKReference represents a foreign key reference to another table's column.
type Parser ¶
type Parser interface {
// Parse parses the SQL from the given file into the internal schema model.
// It can be called multiple times with different files; results accumulate.
Parse(filename string, sql []byte) error
// Schema returns the accumulated schema model.
Schema() *Schema
}
Parser parses SQL DDL statements into a Schema model. Implementations are dialect-specific (PostgreSQL, MySQL, SQLite). A Parser is re-entrant: Parse can be called multiple times with different files, and the schema is accumulated across calls.
type Relationship ¶
type Relationship struct {
Name string
BaseName string
Type RelationshipType
Side RelationshipSide
SourceTable string
TargetTable string
FKColumn string
JunctionTable string
JunctionLocalFK string
JunctionReferenceFK string
Filter string
Sort []RelationshipSort
}
Relationship represents a detected or configured relationship between tables.
BaseName is the pre-disambiguation Name produced at emission time (DetectRelationships) — the child table for O2M, the target table for O2O, the M2M-target table for ManyToMany. When multiple FK edges connect the same (SourceTable, TargetTable) pair, Name is rewritten by disambiguateRelationshipNames to a unique form derived from the FK column (O2M / O2O) or junction table (M2M); BaseName preserves the original so `exclude_relationships` entries written against the bare table name (PRD §4.8 / §13.4) continue to match every disambiguated edge in the group.
type RelationshipSide ¶
type RelationshipSide int
RelationshipSide identifies which end of a relationship edge this entry represents. For O2O / O2M / M2O, "parent" is the FK-holder (source of the directed edge) and "child" is the referenced side. For M2M, both peers are "parent" — the cardinality is symmetric.
const ( // SideUnspecified is the zero value. Production emit paths // (DetectRelationships' addO2O / addO2M / addM2M, plus the codegen's // config-relationship builder) always populate Side, so consumers that // observe SideUnspecified are reading a hand-built fixture that // bypassed those builders — surface that as "no signal" rather than // guessing. SideUnspecified RelationshipSide = iota // SideParent marks the FK-holder end of an O2O / O2M / M2O edge, or // either peer of an M2M edge. SideParent // SideChild marks the referenced end of an O2O / O2M / M2O edge. SideChild )
func (RelationshipSide) String ¶
func (s RelationshipSide) String() string
String returns the string representation of the relationship side.
type RelationshipSort ¶
RelationshipSort defines the ordering for loaded related entities.
type RelationshipType ¶
type RelationshipType int
RelationshipType represents the cardinality of a relationship.
const ( // OneToOne is a one-to-one relationship. OneToOne RelationshipType = iota + 1 // OneToMany is a one-to-many relationship. OneToMany // ManyToMany is a many-to-many relationship. ManyToMany )
func (RelationshipType) String ¶
func (rt RelationshipType) String() string
String returns the string representation of the relationship type.
type Schema ¶
type Schema struct {
Tables []Table
Enums []Enum
Sets []Set
CompositeTypes []CompositeType
DomainTypes []DomainType
Views []View
Relationships []Relationship
Warnings []string
}
Schema is the top-level container for a parsed SQL schema.
type Set ¶
Set represents a MySQL SET type with ordered allowed values. Unlike enums, SET columns store zero or more values as a comma-separated string.
type Table ¶
type Table struct {
Name string
Schema string
Columns []Column
Constraints []Constraint
Comment string
Strict bool // SQLite STRICT table modifier (3.37+)
WithoutRowID bool // SQLite WITHOUT ROWID table modifier (3.8.2+)
}
Table represents a parsed SQL table.
type View ¶
type View struct {
Name string
Schema string
SQL string
Columns []Column
// Materialized reports whether this is a PostgreSQL MATERIALIZED VIEW.
// When true, the generator emits Refresh methods and the FROM clause still
// targets the relation by name (reads are identical to a regular view).
Materialized bool
// ConcurrentlyRefreshable reports whether the matview carries at least one
// UNIQUE index covering all rows — the prerequisite for
// REFRESH MATERIALIZED VIEW CONCURRENTLY. Set during introspection; for
// annotation-file matviews it follows from an @pk directive.
// Always false for regular views (Materialized == false implies
// ConcurrentlyRefreshable == false).
ConcurrentlyRefreshable bool
}
View represents a SQL view (regular or materialized) with its source SQL and inferred columns.
func BuildView ¶
func BuildView(parsed ViewSQL, rawSQL string, annotations *ViewAnnotations, tables []Table) (*View, error)
BuildView constructs a View from pre-parsed SQL metadata, annotations, and known tables. The parsed field is produced by a dialect-specific parser's ParseViewSQL method; annotations come from ParseViewAnnotations.
func MergeViewAnnotations ¶
func MergeViewAnnotations(introspected []View, annotated []View, annotationMap map[string]*ViewAnnotations) []View
MergeViewAnnotations merges annotation overlays onto introspected views. For each view that has a matching annotation file, annotation @pk, @type, and @nullable take precedence over introspected values.
type ViewAnnotations ¶
type ViewAnnotations struct {
PKColumns []string
TypeOverrides map[string]ViewTypeAnnotation
NullableColumns []string
}
ViewAnnotations holds all parsed annotations from a view annotation file.
func ParseViewAnnotations ¶
func ParseViewAnnotations(content string) (*ViewAnnotations, error)
ParseViewAnnotations extracts @pk, @type, and @nullable directives from SQL line comments at the top of a view annotation file.
type ViewSQL ¶
type ViewSQL struct {
Name string
Schema string
Columns []ViewSelectColumn
TableAliases map[string]string
// Materialized reports whether the statement was CREATE MATERIALIZED VIEW
// (PostgreSQL-only; the MySQL/SQLite parsers reject the syntax).
Materialized bool
}
ViewSQL holds the metadata extracted from a CREATE VIEW or CREATE MATERIALIZED VIEW statement by a dialect-specific parser.
type ViewSelectColumn ¶
type ViewSelectColumn struct {
Alias string // output column name (alias or inferred from expression)
SourceTable string // table alias the column comes from (if qualified reference)
SourceColumn string // column name in the source table
Aggregate string // aggregate function name (uppercase), empty if not aggregate
}
ViewSelectColumn represents a column extracted from a view's SELECT clause by a dialect-specific parser.
type ViewTypeAnnotation ¶
ViewTypeAnnotation holds a Go type override from an @type directive.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package introspect provides live database schema introspection capabilities.
|
Package introspect provides live database schema introspection capabilities. |
|
Package mysql provides a MySQL dialect parser using vitess/sqlparser.
|
Package mysql provides a MySQL dialect parser using vitess/sqlparser. |
|
Package postgres provides a PostgreSQL dialect parser using pg_query_go.
|
Package postgres provides a PostgreSQL dialect parser using pg_query_go. |
|
Package sqlite provides a SQLite dialect parser using rqlite/sql.
|
Package sqlite provides a SQLite dialect parser using rqlite/sql. |