Some checks failed
kotlin / test (push) Has been skipped
python / test (push) Has been skipped
typescript / test (push) Has been skipped
go / build darwin/amd64 (push) Has been cancelled
go / build linux/amd64 (push) Has been cancelled
go / build windows/amd64 (push) Has been cancelled
go / build darwin/arm64 (push) Has been cancelled
go / build linux/arm64 (push) Has been cancelled
go / build windows/arm64 (push) Has been cancelled
go / test (push) Has been cancelled
go / vuln_check (push) Has been cancelled
288 lines
7.7 KiB
Go
288 lines
7.7 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/sqlc-dev/sqlc/internal/core/catalogdb"
|
|
)
|
|
|
|
type AttributeSpec struct {
|
|
ClassOID int64
|
|
Name string
|
|
TypeOID int64
|
|
Num int
|
|
NotNull bool
|
|
HasDefault bool
|
|
DeclType string
|
|
AutoIncrement bool
|
|
IsPrimaryKey bool
|
|
IsUnique bool
|
|
// Hidden columns resolve by name but stay out of a star expansion and
|
|
// the relation's model, like the column an sqlite fts5 table names
|
|
// after itself.
|
|
Hidden bool
|
|
}
|
|
|
|
func (c *Catalog) CreateAttributeSpec(s AttributeSpec) error {
|
|
err := c.q.CreateAttribute(context.Background(), catalogdb.CreateAttributeParams{
|
|
ClassOid: s.ClassOID,
|
|
Name: s.Name,
|
|
TypeOid: s.TypeOID,
|
|
NotNull: boolToInt64(s.NotNull),
|
|
HasDefault: boolToInt64(s.HasDefault),
|
|
Num: int64(s.Num),
|
|
DeclType: s.DeclType,
|
|
AutoIncrement: boolToInt64(s.AutoIncrement),
|
|
IsPrimaryKey: boolToInt64(s.IsPrimaryKey),
|
|
IsUnique: boolToInt64(s.IsUnique),
|
|
Hidden: boolToInt64(s.Hidden),
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("create attribute %q on class %d: %w", s.Name, s.ClassOID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Catalog) CreateAttribute(classOID int64, name string, typeOID int64, notNull bool, hasDefault bool, num int) error {
|
|
return c.CreateAttributeSpec(AttributeSpec{
|
|
ClassOID: classOID,
|
|
Name: name,
|
|
TypeOID: typeOID,
|
|
Num: num,
|
|
NotNull: notNull,
|
|
HasDefault: hasDefault,
|
|
})
|
|
}
|
|
|
|
// DropAttribute removes a column from a relation.
|
|
func (c *Catalog) DropAttribute(classOID int64, name string) error {
|
|
err := c.q.DeleteAttribute(context.Background(), catalogdb.DeleteAttributeParams{
|
|
ClassOid: classOID,
|
|
Name: name,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("drop attribute %q on class %d: %w", name, classOID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RenameAttribute renames a column.
|
|
func (c *Catalog) RenameAttribute(classOID int64, name, newName string) error {
|
|
err := c.q.RenameAttribute(context.Background(), catalogdb.RenameAttributeParams{
|
|
ClassOid: classOID,
|
|
Name: name,
|
|
NewName: newName,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("rename attribute %q on class %d: %w", name, classOID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetAttributeType changes a column's type.
|
|
func (c *Catalog) SetAttributeType(classOID int64, name string, typeOID int64, declType string) error {
|
|
err := c.q.SetAttributeType(context.Background(), catalogdb.SetAttributeTypeParams{
|
|
ClassOid: classOID,
|
|
Name: name,
|
|
TypeOid: typeOID,
|
|
DeclType: declType,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("set type of attribute %q on class %d: %w", name, classOID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetAttributeNotNull records whether a column accepts NULL.
|
|
func (c *Catalog) SetAttributeNotNull(classOID int64, name string, notNull bool) error {
|
|
err := c.q.SetAttributeNotNull(context.Background(), catalogdb.SetAttributeNotNullParams{
|
|
ClassOid: classOID,
|
|
Name: name,
|
|
NotNull: boolToInt64(notNull),
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("set null of attribute %q on class %d: %w", name, classOID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// NextAttributeNum is the ordinal a column added to the relation takes.
|
|
func (c *Catalog) NextAttributeNum(classOID int64) (int, error) {
|
|
num, err := c.q.MaxAttributeNum(context.Background(), classOID)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("attribute count for class %d: %w", classOID, err)
|
|
}
|
|
return int(num) + 1, nil
|
|
}
|
|
|
|
func (c *Catalog) SetAttributePrimaryKey(classOID int64, columns []string) error {
|
|
ctx := context.Background()
|
|
for _, name := range columns {
|
|
err := c.q.SetAttributePrimaryKey(ctx, catalogdb.SetAttributePrimaryKeyParams{
|
|
ClassOid: classOID,
|
|
Name: name,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("mark pk %s on class %d: %w", name, classOID, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *Catalog) SetAttributeUnique(classOID int64, columns []string) error {
|
|
ctx := context.Background()
|
|
for _, name := range columns {
|
|
err := c.q.SetAttributeUnique(ctx, catalogdb.SetAttributeUniqueParams{
|
|
ClassOid: classOID,
|
|
Name: name,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("mark unique %s on class %d: %w", name, classOID, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type ColumnInfo struct {
|
|
Name string
|
|
TypeName string
|
|
TypeOID int64
|
|
NotNull bool
|
|
DeclType string
|
|
AutoIncrement bool
|
|
IsPrimaryKey bool
|
|
IsUnique bool
|
|
AttributeOID int64
|
|
ClassOID int64
|
|
}
|
|
|
|
func (c *Catalog) ResolveColumn(table, column string) (*ColumnInfo, error) {
|
|
r, err := c.q.ResolveColumn(context.Background(), catalogdb.ResolveColumnParams{
|
|
TableName: table,
|
|
ColumnName: column,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("resolve %s.%s: %w", table, column, err)
|
|
}
|
|
info := ColumnInfo{
|
|
AttributeOID: r.Oid,
|
|
ClassOID: r.ClassOid,
|
|
Name: r.Name,
|
|
TypeName: r.TypeName,
|
|
TypeOID: r.TypeOid,
|
|
NotNull: r.NotNull != 0,
|
|
DeclType: r.DeclType,
|
|
AutoIncrement: r.AutoIncrement != 0,
|
|
IsPrimaryKey: r.IsPrimaryKey != 0,
|
|
IsUnique: r.IsUnique != 0,
|
|
}
|
|
return &info, nil
|
|
}
|
|
|
|
func (c *Catalog) TableColumns(table string) ([]ColumnInfo, error) {
|
|
rows, err := c.q.TableColumns(context.Background(), table)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("table columns %q: %w", table, err)
|
|
}
|
|
cols := make([]ColumnInfo, 0, len(rows))
|
|
for _, r := range rows {
|
|
cols = append(cols, ColumnInfo{
|
|
AttributeOID: r.Oid,
|
|
ClassOID: r.ClassOid,
|
|
Name: r.Name,
|
|
TypeName: r.TypeName,
|
|
TypeOID: r.TypeOid,
|
|
NotNull: r.NotNull != 0,
|
|
DeclType: r.DeclType,
|
|
AutoIncrement: r.AutoIncrement != 0,
|
|
IsPrimaryKey: r.IsPrimaryKey != 0,
|
|
IsUnique: r.IsUnique != 0,
|
|
})
|
|
}
|
|
return cols, nil
|
|
}
|
|
|
|
type ClassColumn struct {
|
|
AttOID int64
|
|
Name string
|
|
TypeOID int64
|
|
// Type is the column's type as an expression, set for a column of a
|
|
// derived relation whose type the catalog holds no row for, or holds
|
|
// only the family of.
|
|
Type *TypeExpr
|
|
NotNull bool
|
|
Hidden bool
|
|
}
|
|
|
|
// ClassColumns returns a relation's columns in ordinal order.
|
|
func (c *Catalog) ClassColumns(classOID int64) ([]ClassColumn, error) {
|
|
rows, err := c.q.ClassAttributes(context.Background(), classOID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("class columns %d: %w", classOID, err)
|
|
}
|
|
out := make([]ClassColumn, 0, len(rows))
|
|
for _, r := range rows {
|
|
out = append(out, ClassColumn{
|
|
AttOID: r.Oid,
|
|
Name: r.Name,
|
|
TypeOID: r.TypeOid,
|
|
NotNull: r.NotNull != 0,
|
|
Hidden: r.Hidden != 0,
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
type CodegenColumn struct {
|
|
Name string
|
|
TypeOID int64
|
|
NotNull bool
|
|
}
|
|
|
|
func (c *Catalog) ClassCodegenColumns(classOID int64) ([]CodegenColumn, error) {
|
|
rows, err := c.q.ListClassColumns(context.Background(), classOID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("class codegen columns %d: %w", classOID, err)
|
|
}
|
|
out := make([]CodegenColumn, 0, len(rows))
|
|
for _, r := range rows {
|
|
out = append(out, CodegenColumn{
|
|
Name: r.ColumnName,
|
|
TypeOID: r.TypeOid,
|
|
NotNull: r.NotNull != 0,
|
|
})
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
type AttributeDetails struct {
|
|
Schema string
|
|
Table string
|
|
Column string
|
|
Num int
|
|
DeclType string
|
|
AutoIncrement bool
|
|
IsPrimaryKey bool
|
|
IsUnique bool
|
|
NotNull bool
|
|
}
|
|
|
|
func (c *Catalog) LookupAttribute(attOID int64) (AttributeDetails, error) {
|
|
r, err := c.q.LookupAttribute(context.Background(), attOID)
|
|
if err != nil {
|
|
return AttributeDetails{}, fmt.Errorf("lookup attribute %d: %w", attOID, err)
|
|
}
|
|
return AttributeDetails{
|
|
Schema: r.SchemaName,
|
|
Table: r.TableName,
|
|
Column: r.ColumnName,
|
|
Num: int(r.Num),
|
|
DeclType: r.DeclType,
|
|
AutoIncrement: r.AutoIncrement != 0,
|
|
IsPrimaryKey: r.IsPrimaryKey != 0,
|
|
IsUnique: r.IsUnique != 0,
|
|
NotNull: r.NotNull != 0,
|
|
}, nil
|
|
}
|