-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdberd.go
More file actions
135 lines (115 loc) · 4.05 KB
/
dberd.go
File metadata and controls
135 lines (115 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Package dberd provides functionality for database schema extraction, formatting, and rendering.
package dberd
import (
"context"
"fmt"
"io"
"sort"
)
// TargetType represents the type of language for describing database schema.
type TargetType string
// Schema represents a complete database schema with tables and their references.
type Schema struct {
Tables []Table `json:"tables"`
References []Reference `json:"references"`
}
// Sort sorts the schema's tables and references in a consistent order.
func (s *Schema) Sort() {
sort.Slice(s.Tables, func(i, j int) bool {
return s.Tables[i].Name < s.Tables[j].Name
})
for i := range s.Tables {
sort.Slice(s.Tables[i].Columns, func(j, k int) bool {
if s.Tables[i].Columns[j].IsPrimary != s.Tables[i].Columns[k].IsPrimary {
return s.Tables[i].Columns[j].IsPrimary
}
if s.Tables[i].Columns[j].Definition != s.Tables[i].Columns[k].Definition {
return s.Tables[i].Columns[j].Definition < s.Tables[i].Columns[k].Definition
}
return s.Tables[i].Columns[j].Name < s.Tables[i].Columns[k].Name
})
}
sort.Slice(s.References, func(i, j int) bool {
switch {
case s.References[i].Source.Table != s.References[j].Source.Table:
return s.References[i].Source.Table < s.References[j].Source.Table
case s.References[i].Source.Column != s.References[j].Source.Column:
return s.References[i].Source.Column < s.References[j].Source.Column
case s.References[i].Target.Table != s.References[j].Target.Table:
return s.References[i].Target.Table < s.References[j].Target.Table
default:
return s.References[i].Target.Column < s.References[j].Target.Column
}
})
}
// Table represents a database table with its columns.
type Table struct {
Name string `json:"name"`
Columns []Column `json:"columns"`
}
// Column represents a database table column.
type Column struct {
Name string `json:"name"`
Comment string `json:"comment,omitempty"`
Definition string `json:"definition"`
IsPrimary bool `json:"is_primary"`
}
// TableColumn represents a reference to a specific column in a table.
type TableColumn struct {
Table string `json:"table"`
Column string `json:"column"`
}
// Reference represents a foreign key relationship between two table columns.
type Reference struct {
Source TableColumn `json:"source"`
Target TableColumn `json:"target"`
}
// FormattedSchema represents a formatted database schema.
type FormattedSchema struct {
Type TargetType `json:"type"`
Data []byte `json:"data"`
}
// TargetCapabilities represents the capabilities of a Target implementation.
type TargetCapabilities struct {
Format bool
Render bool
}
// Source defines the interface for database schema sources that can extract schema information.
type Source interface {
SchemaExtractor
io.Closer
}
// Target defines the interface for database schema targets that can format and render schema information.
type Target interface {
SchemaFormatter
SchemaRenderer
Capabilities() TargetCapabilities
}
// SchemaExtractor defines the interface for extracting database schema.
type SchemaExtractor interface {
ExtractSchema(ctx context.Context) (Schema, error)
}
// SchemaFormatter defines the interface for formatting database schema.
type SchemaFormatter interface {
FormatSchema(ctx context.Context, s Schema) (FormattedSchema, error)
}
// SchemaRenderer defines the interface for rendering formatted database schema.
type SchemaRenderer interface {
RenderSchema(ctx context.Context, fs FormattedSchema) ([]byte, error)
}
// UnsupportedFormatError represents an error when an unsupported format is provided.
type UnsupportedFormatError struct {
given TargetType
expected TargetType
}
// NewUnsupportedFormatError creates a new UnsupportedFormatError.
func NewUnsupportedFormatError(given, expected TargetType) error {
return &UnsupportedFormatError{
given: given,
expected: expected,
}
}
// Error implements the error interface for UnsupportedFormatError.
func (err *UnsupportedFormatError) Error() string {
return fmt.Sprintf("%s format is not supported, %s expected", err.given, err.expected)
}