github.com/kunlun-qilian/sqlx/v3@v3.0.0/er/er.go (about) 1 package er 2 3 import ( 4 "context" 5 "strings" 6 7 typex "github.com/go-courier/x/types" 8 9 "github.com/go-courier/enumeration" 10 "github.com/kunlun-qilian/sqlx/v3" 11 "github.com/kunlun-qilian/sqlx/v3/builder" 12 ) 13 14 func DatabaseERFromDB(database *sqlx.Database, dialect builder.Dialect) *ERDatabase { 15 erd := &ERDatabase{Name: database.Name, Tables: map[string]*ERTable{}} 16 17 database.Tables.Range(func(table *builder.Table, idx int) { 18 t := &ERTable{Name: table.Name, Cols: map[string]*ERCol{}, Keys: map[string]*ERKey{}} 19 20 if len(table.Description) > 0 { 21 t.Summary = table.Description[0] 22 23 if len(table.Description) > 1 { 24 t.Desc = strings.Join(table.Description[1:], "\n") 25 } 26 } 27 28 erd.Tables[t.Name] = t 29 30 table.Columns.Range(func(col *builder.Column, idx int) { 31 if col.DeprecatedActions != nil { 32 return 33 } 34 35 c := &ERCol{ 36 Name: col.Name, 37 DataType: builder.ResolveExpr(dialect.DataType(col.ColumnType)).Query(), 38 } 39 40 if len(col.Description) > 0 { 41 c.Summary = col.Description[0] 42 43 if len(col.Description) > 1 { 44 c.Desc = strings.Join(col.Description[1:], "\n") 45 } 46 } 47 48 if rv, ok := typex.TryNew(col.ColumnType.Type); ok { 49 if rv.CanInterface() { 50 if emum, ok := rv.Interface().(enumeration.Enum); ok { 51 52 c.Enum = map[string]EREnum{} 53 54 for _, e := range emum.ConstValues() { 55 em := EREnum{} 56 em.Value = e.Int() 57 em.Name = e.String() 58 em.Label = e.Label() 59 60 c.Enum[em.Name] = em 61 } 62 } 63 } 64 } 65 66 if len(col.Relation) == 2 { 67 relTable := database.Tables.Model(col.Relation[0]) 68 if relTable != nil && relTable != table { 69 relCol := relTable.F(col.Relation[1]) 70 if relCol != nil { 71 c.Rel = []string{ 72 relTable.Name, 73 relCol.Name, 74 } 75 } 76 } 77 } 78 79 t.Cols[c.Name] = c 80 }) 81 82 table.Keys.Range(func(key *builder.Key, idx int) { 83 k := &ERKey{ 84 Name: key.Name, 85 Method: key.Method, 86 IsUnique: key.IsUnique, 87 IsPrimary: key.Name == "primary", 88 } 89 90 if q := key.Def.TableExpr(table).Ex(context.Background()).Query(); q != "" { 91 // todo rename 92 k.Cols = []string{q} 93 } 94 95 t.Keys[k.Name] = k 96 }) 97 }) 98 99 return erd 100 } 101 102 type ERDatabase struct { 103 Name string `json:"name"` 104 Tables map[string]*ERTable `json:"tables"` 105 } 106 107 type ERTable struct { 108 Name string `json:"name"` 109 Summary string `json:"summary"` 110 Desc string `json:"desc"` 111 Cols map[string]*ERCol `json:"cols"` 112 Keys map[string]*ERKey `json:"keys"` 113 } 114 115 type ERCol struct { 116 Name string `json:"name"` 117 DataType string `json:"dataType"` 118 Enum map[string]EREnum `json:"enum"` 119 Summary string `json:"summary"` 120 Desc string `json:"desc"` 121 Rel []string `json:"rel"` 122 } 123 124 type EREnum struct { 125 Value int `json:"value"` 126 Name string `json:"name"` 127 Label string `json:"label"` 128 } 129 130 type ERKey struct { 131 Name string `json:"name"` 132 Method string `json:"method"` 133 IsUnique bool `json:"isUnique"` 134 IsPrimary bool `json:"isPrimary"` 135 Cols []string `json:"cols"` 136 }