feat(domains): ✨ add domain support for DrawDB integration
- Introduce Domain and DomainTable models for logical grouping of tables. - Implement export and import functionality for domains in DrawDB format. - Update template execution modes to include domain processing. - Enhance documentation for domain features and usage.
This commit is contained in:
149
docs/DOMAINS_DRAWDB.md
Normal file
149
docs/DOMAINS_DRAWDB.md
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
# Domains and DrawDB Areas Integration
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Domains provide a way to organize tables from potentially multiple schemas into logical business groupings. When working with DrawDB format, domains are automatically imported/exported as **Subject Areas** - a native DrawDB feature for visually grouping tables.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
### Writing Domains to DrawDB (Export)
|
||||||
|
|
||||||
|
When you export a database with domains to DrawDB format:
|
||||||
|
|
||||||
|
1. **Schema Areas** are created automatically for each schema (existing behavior)
|
||||||
|
2. **Domain Areas** are created for each domain, calculated based on the positions of the tables they contain
|
||||||
|
3. The domain area bounds are automatically calculated to encompass all its tables with a small padding
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Example: Creating a domain and exporting to DrawDB
|
||||||
|
db := models.InitDatabase("mydb")
|
||||||
|
|
||||||
|
// Create an "authentication" domain
|
||||||
|
authDomain := models.InitDomain("authentication")
|
||||||
|
authDomain.Tables = append(authDomain.Tables,
|
||||||
|
models.InitDomainTable("users", "public"),
|
||||||
|
models.InitDomainTable("roles", "public"),
|
||||||
|
models.InitDomainTable("permissions", "public"),
|
||||||
|
)
|
||||||
|
db.Domains = append(db.Domains, authDomain)
|
||||||
|
|
||||||
|
// Create a "financial" domain spanning multiple schemas
|
||||||
|
finDomain := models.InitDomain("financial")
|
||||||
|
finDomain.Tables = append(finDomain.Tables,
|
||||||
|
models.InitDomainTable("accounts", "public"),
|
||||||
|
models.InitDomainTable("transactions", "public"),
|
||||||
|
models.InitDomainTable("ledger", "finance"), // Different schema!
|
||||||
|
)
|
||||||
|
db.Domains = append(db.Domains, finDomain)
|
||||||
|
|
||||||
|
// Write to DrawDB - domains become subject areas
|
||||||
|
writer := drawdb.NewWriter(&writers.WriterOptions{
|
||||||
|
OutputPath: "schema.json",
|
||||||
|
})
|
||||||
|
writer.WriteDatabase(db)
|
||||||
|
```
|
||||||
|
|
||||||
|
The resulting DrawDB JSON will have Subject Areas for both:
|
||||||
|
- "authentication" area containing the auth tables
|
||||||
|
- "financial" area containing the financial tables from both schemas
|
||||||
|
|
||||||
|
### Reading Domains from DrawDB (Import)
|
||||||
|
|
||||||
|
When you import a DrawDB file with Subject Areas:
|
||||||
|
|
||||||
|
1. **Subject Areas** are automatically converted to **Domains**
|
||||||
|
2. Tables are assigned to a domain if they fall within the area's visual bounds
|
||||||
|
3. Table references include both the table name and schema name
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Example: Reading DrawDB with areas
|
||||||
|
reader := drawdb.NewReader(&readers.ReaderOptions{
|
||||||
|
FilePath: "schema.json",
|
||||||
|
})
|
||||||
|
|
||||||
|
db, err := reader.ReadDatabase()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access domains
|
||||||
|
for _, domain := range db.Domains {
|
||||||
|
fmt.Printf("Domain: %s\n", domain.Name)
|
||||||
|
for _, domainTable := range domain.Tables {
|
||||||
|
fmt.Printf(" - %s.%s\n", domainTable.SchemaName, domainTable.TableName)
|
||||||
|
|
||||||
|
// Access the actual table reference if loaded
|
||||||
|
if domainTable.RefTable != nil {
|
||||||
|
fmt.Printf(" Description: %s\n", domainTable.RefTable.Description)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Domain Structure
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Domain struct {
|
||||||
|
Name string // Domain name (e.g., "authentication", "user_data")
|
||||||
|
Description string // Optional human-readable description
|
||||||
|
Tables []*DomainTable // Tables belonging to this domain
|
||||||
|
Comment string // Optional comment
|
||||||
|
Metadata map[string]any // Extensible metadata
|
||||||
|
Sequence uint // Ordering hint
|
||||||
|
}
|
||||||
|
|
||||||
|
type DomainTable struct {
|
||||||
|
TableName string // Table name
|
||||||
|
SchemaName string // Schema containing the table
|
||||||
|
Sequence uint // Ordering hint
|
||||||
|
RefTable *Table // Pointer to actual table (in-memory only, not serialized)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Multi-Schema Domains
|
||||||
|
|
||||||
|
One of the key features of domains is that they can span multiple schemas:
|
||||||
|
|
||||||
|
```
|
||||||
|
Domain: "user_data"
|
||||||
|
├── public.users
|
||||||
|
├── public.profiles
|
||||||
|
├── public.user_preferences
|
||||||
|
├── auth.user_sessions
|
||||||
|
└── auth.mfa_devices
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows you to organize related tables even when they're stored in different schemas.
|
||||||
|
|
||||||
|
## Visual Organization in DrawDB
|
||||||
|
|
||||||
|
When viewing the exported DrawDB file in DrawDB Editor:
|
||||||
|
|
||||||
|
1. **Schema areas** appear in one color (original behavior)
|
||||||
|
2. **Domain areas** appear in a different color
|
||||||
|
3. Domain area bounds are calculated to fit all contained tables
|
||||||
|
4. Areas can overlap - a table can visually belong to multiple areas
|
||||||
|
|
||||||
|
## Integration with Other Formats
|
||||||
|
|
||||||
|
Currently, domain/area integration is implemented for DrawDB format.
|
||||||
|
|
||||||
|
To implement similar functionality for other formats:
|
||||||
|
|
||||||
|
1. Identify if the format has a native grouping/area feature
|
||||||
|
2. Add conversion logic in the reader to map format areas → Domain model
|
||||||
|
3. Add conversion logic in the writer to map Domain model → format areas
|
||||||
|
|
||||||
|
Example formats that could support domains:
|
||||||
|
- **DBML**: Could use DBML's `TableGroup` feature
|
||||||
|
- **DrawDB**: ✅ Already implemented (Subject Areas)
|
||||||
|
- **GraphQL**: Could use schema directives
|
||||||
|
- **Custom formats**: Implement as needed
|
||||||
|
|
||||||
|
## Tips and Best Practices
|
||||||
|
|
||||||
|
1. **Keep domains focused**: Each domain should represent a distinct business area
|
||||||
|
2. **Document purposes**: Use Description and Comment fields to explain each domain
|
||||||
|
3. **Use meaningful names**: Domain names should clearly reflect their purpose
|
||||||
|
4. **Maintain schema consistency**: Keep related tables together in the same schema when possible
|
||||||
|
5. **Use metadata**: Store tool-specific information in the Metadata field
|
||||||
@@ -44,12 +44,13 @@ The `--mode` flag controls how the template is executed:
|
|||||||
|------|-------------|--------|-------------|
|
|------|-------------|--------|-------------|
|
||||||
| `database` | Execute once for entire database | Single file | Documentation, reports, overview files |
|
| `database` | Execute once for entire database | Single file | Documentation, reports, overview files |
|
||||||
| `schema` | Execute once per schema | One file per schema | Schema-specific documentation |
|
| `schema` | Execute once per schema | One file per schema | Schema-specific documentation |
|
||||||
|
| `domain` | Execute once per domain | One file per domain | Domain-based documentation, domain exports |
|
||||||
| `script` | Execute once per script | One file per script | Script processing |
|
| `script` | Execute once per script | One file per script | Script processing |
|
||||||
| `table` | Execute once per table | One file per table | Model generation, table docs |
|
| `table` | Execute once per table | One file per table | Model generation, table docs |
|
||||||
|
|
||||||
### Filename Patterns
|
### Filename Patterns
|
||||||
|
|
||||||
For multi-file modes (`schema`, `script`, `table`), use `--filename-pattern` to control output filenames:
|
For multi-file modes (`schema`, `domain`, `script`, `table`), use `--filename-pattern` to control output filenames:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Default pattern
|
# Default pattern
|
||||||
@@ -296,6 +297,13 @@ The data available in templates depends on the execution mode:
|
|||||||
.Metadata // map[string]interface{} - User metadata
|
.Metadata // map[string]interface{} - User metadata
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Domain Mode
|
||||||
|
```go
|
||||||
|
.Domain // *models.Domain - Current domain
|
||||||
|
.ParentDatabase // *models.Database - Parent database context
|
||||||
|
.Metadata // map[string]interface{} - User metadata
|
||||||
|
```
|
||||||
|
|
||||||
### Table Mode
|
### Table Mode
|
||||||
```go
|
```go
|
||||||
.Table // *models.Table - Current table
|
.Table // *models.Table - Current table
|
||||||
@@ -317,6 +325,7 @@ The data available in templates depends on the execution mode:
|
|||||||
**Database:**
|
**Database:**
|
||||||
- `.Name` - Database name
|
- `.Name` - Database name
|
||||||
- `.Schemas` - List of schemas
|
- `.Schemas` - List of schemas
|
||||||
|
- `.Domains` - List of domains (business domain groupings)
|
||||||
- `.Description`, `.Comment` - Documentation
|
- `.Description`, `.Comment` - Documentation
|
||||||
|
|
||||||
**Schema:**
|
**Schema:**
|
||||||
@@ -325,6 +334,17 @@ The data available in templates depends on the execution mode:
|
|||||||
- `.Views`, `.Sequences`, `.Scripts` - Other objects
|
- `.Views`, `.Sequences`, `.Scripts` - Other objects
|
||||||
- `.Enums` - Enum types
|
- `.Enums` - Enum types
|
||||||
|
|
||||||
|
**Domain:**
|
||||||
|
- `.Name` - Domain name
|
||||||
|
- `.Tables` - List of DomainTable references
|
||||||
|
- `.Description`, `.Comment` - Documentation
|
||||||
|
- `.Metadata` - Custom metadata map
|
||||||
|
|
||||||
|
**DomainTable:**
|
||||||
|
- `.TableName` - Name of the table
|
||||||
|
- `.SchemaName` - Schema containing the table
|
||||||
|
- `.RefTable` - Pointer to actual Table object (if loaded)
|
||||||
|
|
||||||
**Table:**
|
**Table:**
|
||||||
- `.Name` - Table name
|
- `.Name` - Table name
|
||||||
- `.Schema` - Schema name
|
- `.Schema` - Schema name
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type Database struct {
|
|||||||
Name string `json:"name" yaml:"name"`
|
Name string `json:"name" yaml:"name"`
|
||||||
Description string `json:"description,omitempty" yaml:"description,omitempty" xml:"description,omitempty"`
|
Description string `json:"description,omitempty" yaml:"description,omitempty" xml:"description,omitempty"`
|
||||||
Schemas []*Schema `json:"schemas" yaml:"schemas" xml:"schemas"`
|
Schemas []*Schema `json:"schemas" yaml:"schemas" xml:"schemas"`
|
||||||
|
Domains []*Domain `json:"domains,omitempty" yaml:"domains,omitempty" xml:"domains,omitempty"`
|
||||||
Comment string `json:"comment,omitempty" yaml:"comment,omitempty" xml:"comment,omitempty"`
|
Comment string `json:"comment,omitempty" yaml:"comment,omitempty" xml:"comment,omitempty"`
|
||||||
DatabaseType DatabaseType `json:"database_type,omitempty" yaml:"database_type,omitempty" xml:"database_type,omitempty"`
|
DatabaseType DatabaseType `json:"database_type,omitempty" yaml:"database_type,omitempty" xml:"database_type,omitempty"`
|
||||||
DatabaseVersion string `json:"database_version,omitempty" yaml:"database_version,omitempty" xml:"database_version,omitempty"`
|
DatabaseVersion string `json:"database_version,omitempty" yaml:"database_version,omitempty" xml:"database_version,omitempty"`
|
||||||
@@ -32,6 +33,32 @@ func (d *Database) SQLName() string {
|
|||||||
return strings.ToLower(d.Name)
|
return strings.ToLower(d.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Domain represents a logical business domain grouping multiple tables from potentially different schemas.
|
||||||
|
// Domains allow for organizing database tables by functional areas (e.g., authentication, user data, financial).
|
||||||
|
type Domain struct {
|
||||||
|
Name string `json:"name" yaml:"name" xml:"name"`
|
||||||
|
Description string `json:"description,omitempty" yaml:"description,omitempty" xml:"description,omitempty"`
|
||||||
|
Tables []*DomainTable `json:"tables" yaml:"tables" xml:"tables"`
|
||||||
|
Comment string `json:"comment,omitempty" yaml:"comment,omitempty" xml:"comment,omitempty"`
|
||||||
|
Metadata map[string]any `json:"metadata,omitempty" yaml:"metadata,omitempty" xml:"-"`
|
||||||
|
Sequence uint `json:"sequence,omitempty" yaml:"sequence,omitempty" xml:"sequence,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SQLName returns the domain name in lowercase for SQL compatibility.
|
||||||
|
func (d *Domain) SQLName() string {
|
||||||
|
return strings.ToLower(d.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DomainTable represents a reference to a specific table within a domain.
|
||||||
|
// It identifies the table by name and schema, allowing a single domain to include
|
||||||
|
// tables from multiple schemas.
|
||||||
|
type DomainTable struct {
|
||||||
|
TableName string `json:"table_name" yaml:"table_name" xml:"table_name"`
|
||||||
|
SchemaName string `json:"schema_name" yaml:"schema_name" xml:"schema_name"`
|
||||||
|
Sequence uint `json:"sequence,omitempty" yaml:"sequence,omitempty" xml:"sequence,omitempty"`
|
||||||
|
RefTable *Table `json:"-" yaml:"-" xml:"-"` // Excluded to prevent circular references
|
||||||
|
}
|
||||||
|
|
||||||
// Schema represents a database schema, which is a logical grouping of database objects
|
// Schema represents a database schema, which is a logical grouping of database objects
|
||||||
// such as tables, views, sequences, and relationships within a database.
|
// such as tables, views, sequences, and relationships within a database.
|
||||||
type Schema struct {
|
type Schema struct {
|
||||||
@@ -295,6 +322,7 @@ func InitDatabase(name string) *Database {
|
|||||||
return &Database{
|
return &Database{
|
||||||
Name: name,
|
Name: name,
|
||||||
Schemas: make([]*Schema, 0),
|
Schemas: make([]*Schema, 0),
|
||||||
|
Domains: make([]*Domain, 0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,3 +430,20 @@ func InitSequence(name, schema string) *Sequence {
|
|||||||
StartValue: 1,
|
StartValue: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitDomain initializes a new Domain with empty slices and maps
|
||||||
|
func InitDomain(name string) *Domain {
|
||||||
|
return &Domain{
|
||||||
|
Name: name,
|
||||||
|
Tables: make([]*DomainTable, 0),
|
||||||
|
Metadata: make(map[string]any),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitDomainTable initializes a new DomainTable reference
|
||||||
|
func InitDomainTable(tableName, schemaName string) *DomainTable {
|
||||||
|
return &DomainTable{
|
||||||
|
TableName: tableName,
|
||||||
|
SchemaName: schemaName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -140,6 +140,32 @@ func (r *Reader) convertToDatabase(drawSchema *drawdb.DrawDBSchema) (*models.Dat
|
|||||||
db.Schemas = append(db.Schemas, schema)
|
db.Schemas = append(db.Schemas, schema)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert DrawDB subject areas to domains
|
||||||
|
for _, area := range drawSchema.SubjectAreas {
|
||||||
|
domain := models.InitDomain(area.Name)
|
||||||
|
|
||||||
|
// Find all tables that visually belong to this area
|
||||||
|
// A table belongs to an area if its position is within the area bounds
|
||||||
|
for _, drawTable := range drawSchema.Tables {
|
||||||
|
if drawTable.X >= area.X && drawTable.X <= (area.X+area.Width) &&
|
||||||
|
drawTable.Y >= area.Y && drawTable.Y <= (area.Y+area.Height) {
|
||||||
|
|
||||||
|
schemaName := drawTable.Schema
|
||||||
|
if schemaName == "" {
|
||||||
|
schemaName = "public"
|
||||||
|
}
|
||||||
|
|
||||||
|
domainTable := models.InitDomainTable(drawTable.Name, schemaName)
|
||||||
|
domain.Tables = append(domain.Tables, domainTable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only add domain if it has tables
|
||||||
|
if len(domain.Tables) > 0 {
|
||||||
|
db.Domains = append(db.Domains, domain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,51 @@ func (w *Writer) databaseToDrawDB(d *models.Database) *DrawDBSchema {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create subject areas for domains
|
||||||
|
for domainIdx, domainModel := range d.Domains {
|
||||||
|
// Calculate bounds for all tables in this domain
|
||||||
|
minX, minY := 999999, 999999
|
||||||
|
maxX, maxY := 0, 0
|
||||||
|
|
||||||
|
domainTableCount := 0
|
||||||
|
for _, domainTable := range domainModel.Tables {
|
||||||
|
// Find the table in the schema to get its position
|
||||||
|
for _, t := range schema.Tables {
|
||||||
|
if t.Name == domainTable.TableName {
|
||||||
|
if t.X < minX {
|
||||||
|
minX = t.X
|
||||||
|
}
|
||||||
|
if t.Y < minY {
|
||||||
|
minY = t.Y
|
||||||
|
}
|
||||||
|
if t.X+colWidth > maxX {
|
||||||
|
maxX = t.X + colWidth
|
||||||
|
}
|
||||||
|
if t.Y+rowHeight > maxY {
|
||||||
|
maxY = t.Y + rowHeight
|
||||||
|
}
|
||||||
|
domainTableCount++
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only create area if domain has tables in this schema
|
||||||
|
if domainTableCount > 0 {
|
||||||
|
area := &DrawDBArea{
|
||||||
|
ID: areaID,
|
||||||
|
Name: domainModel.Name,
|
||||||
|
Color: getColorForIndex(len(d.Schemas) + domainIdx), // Use different colors than schemas
|
||||||
|
X: minX - 20,
|
||||||
|
Y: minY - 20,
|
||||||
|
Width: maxX - minX + 40,
|
||||||
|
Height: maxY - minY + 40,
|
||||||
|
}
|
||||||
|
schema.SubjectAreas = append(schema.SubjectAreas, area)
|
||||||
|
areaID++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add relationships
|
// Add relationships
|
||||||
for _, schemaModel := range d.Schemas {
|
for _, schemaModel := range d.Schemas {
|
||||||
for _, table := range schemaModel.Tables {
|
for _, table := range schemaModel.Tables {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ type TemplateData struct {
|
|||||||
// One of these will be populated based on execution mode
|
// One of these will be populated based on execution mode
|
||||||
Database *models.Database
|
Database *models.Database
|
||||||
Schema *models.Schema
|
Schema *models.Schema
|
||||||
|
Domain *models.Domain
|
||||||
Script *models.Script
|
Script *models.Script
|
||||||
Table *models.Table
|
Table *models.Table
|
||||||
|
|
||||||
@@ -57,6 +58,15 @@ func NewSchemaData(schema *models.Schema, metadata map[string]interface{}) *Temp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDomainData creates template data for domain mode
|
||||||
|
func NewDomainData(domain *models.Domain, db *models.Database, metadata map[string]interface{}) *TemplateData {
|
||||||
|
return &TemplateData{
|
||||||
|
Domain: domain,
|
||||||
|
ParentDatabase: db,
|
||||||
|
Metadata: metadata,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NewScriptData creates template data for script mode
|
// NewScriptData creates template data for script mode
|
||||||
func NewScriptData(script *models.Script, schema *models.Schema, db *models.Database, metadata map[string]interface{}) *TemplateData {
|
func NewScriptData(script *models.Script, schema *models.Schema, db *models.Database, metadata map[string]interface{}) *TemplateData {
|
||||||
return &TemplateData{
|
return &TemplateData{
|
||||||
@@ -85,6 +95,9 @@ func (td *TemplateData) Name() string {
|
|||||||
if td.Schema != nil {
|
if td.Schema != nil {
|
||||||
return td.Schema.Name
|
return td.Schema.Name
|
||||||
}
|
}
|
||||||
|
if td.Domain != nil {
|
||||||
|
return td.Domain.Name
|
||||||
|
}
|
||||||
if td.Script != nil {
|
if td.Script != nil {
|
||||||
return td.Script.Name
|
return td.Script.Name
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ const (
|
|||||||
DatabaseMode EntrypointMode = "database"
|
DatabaseMode EntrypointMode = "database"
|
||||||
// SchemaMode executes the template once per schema (multi-file output)
|
// SchemaMode executes the template once per schema (multi-file output)
|
||||||
SchemaMode EntrypointMode = "schema"
|
SchemaMode EntrypointMode = "schema"
|
||||||
|
// DomainMode executes the template once per domain (multi-file output)
|
||||||
|
DomainMode EntrypointMode = "domain"
|
||||||
// ScriptMode executes the template once per script (multi-file output)
|
// ScriptMode executes the template once per script (multi-file output)
|
||||||
ScriptMode EntrypointMode = "script"
|
ScriptMode EntrypointMode = "script"
|
||||||
// TableMode executes the template once per table (multi-file output)
|
// TableMode executes the template once per table (multi-file output)
|
||||||
@@ -80,6 +82,8 @@ func (w *Writer) WriteDatabase(db *models.Database) error {
|
|||||||
return w.executeDatabaseMode(db)
|
return w.executeDatabaseMode(db)
|
||||||
case SchemaMode:
|
case SchemaMode:
|
||||||
return w.executeSchemaMode(db)
|
return w.executeSchemaMode(db)
|
||||||
|
case DomainMode:
|
||||||
|
return w.executeDomainMode(db)
|
||||||
case ScriptMode:
|
case ScriptMode:
|
||||||
return w.executeScriptMode(db)
|
return w.executeScriptMode(db)
|
||||||
case TableMode:
|
case TableMode:
|
||||||
@@ -143,6 +147,28 @@ func (w *Writer) executeSchemaMode(db *models.Database) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executeDomainMode executes the template once per domain
|
||||||
|
func (w *Writer) executeDomainMode(db *models.Database) error {
|
||||||
|
for _, domain := range db.Domains {
|
||||||
|
data := NewDomainData(domain, db, w.options.Metadata)
|
||||||
|
output, err := w.executeTemplate(data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute template for domain %s: %w", domain.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filename, err := w.generateFilename(data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to generate filename for domain %s: %w", domain.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := w.writeOutput(output, filename); err != nil {
|
||||||
|
return fmt.Errorf("failed to write output for domain %s: %w", domain.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// executeScriptMode executes the template once per script
|
// executeScriptMode executes the template once per script
|
||||||
func (w *Writer) executeScriptMode(db *models.Database) error {
|
func (w *Writer) executeScriptMode(db *models.Database) error {
|
||||||
for _, schema := range db.Schemas {
|
for _, schema := range db.Schemas {
|
||||||
|
|||||||
Reference in New Issue
Block a user