package schema import ( "encoding/json" "fmt" ) type Table struct { Name string `json:"table"` Schema []Field `json:"schema"` } type Field struct { Name string `json:"name"` Type string `json:"type"` Nullable *bool `json:"nullable"` Default *string `json:"default"` Unique *bool `json:"unique"` Primary *bool `json:"primary"` Comment *string `json:"comment"` References *Reference `json:"references"` Algorithm *string `json:"algorithm"` } type Reference struct { Table string `json:"table"` Column string `json:"column"` OnDelete string `json:"onDelete"` OnUpdate string `json:"onUpdate"` } // Mapping of field types to SQL types var fieldTypeToSQLType = map[string]string{ "string": "VARCHAR", "int": "INTEGER", "float": "FLOAT", "bool": "BOOLEAN", "date": "DATE", "time": "TIME", "datetime": "TIMESTAMP", "uuid": "UUID", "json": "JSONB", "hash": "VARCHAR", } func NewTable(data []byte) (*Table, error) { var table Table err := json.Unmarshal(data, &table) if err != nil { return nil, err } return &table, nil } func (t *Table) JSON() ([]byte, error) { return json.Marshal(t) } func (f *Field) SQL() string { sqlType := fieldTypeToSQLType[f.Type] if sqlType == "" { return "" } sql := fmt.Sprintf("%s %s", f.Name, sqlType) if f.Nullable != nil && !*f.Nullable { sql += " NOT NULL" } if f.Primary != nil && *f.Primary { sql += " PRIMARY KEY" if f.Default == nil && f.Type == "uuid" { sql += " DEFAULT uuid_generate_v4()" } } if f.Unique != nil && *f.Unique { sql += " UNIQUE" } if f.Default != nil && f.Primary == nil { sql += fmt.Sprintf(" DEFAULT %s", *f.Default) } if f.References != nil { sql += fmt.Sprintf(" REFERENCES %s(%s)", f.References.Table, f.References.Column) if f.References.OnDelete != "" { sql += fmt.Sprintf(" ON DELETE %s", f.References.OnDelete) } if f.References.OnUpdate != "" { sql += fmt.Sprintf(" ON UPDATE %s", f.References.OnUpdate) } } return sql } func (f *Field) SQLReferences() string { if f.References == nil { return "" } return fmt.Sprintf(" REFERENCES %s(%s)", f.References.Table, f.References.Column) }