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  }