support foreign key.添加 外键支持
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
var mysqlInfo config.MysqlDbInfo
|
||||
var outDir string
|
||||
var singularTable bool
|
||||
var foreignKey bool
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "main",
|
||||
@@ -56,6 +57,9 @@ func init() {
|
||||
rootCmd.PersistentFlags().BoolVarP(&singularTable, "singular", "s", false, "是否禁用表名复数")
|
||||
rootCmd.MarkFlagRequired("singular")
|
||||
|
||||
rootCmd.PersistentFlags().BoolVarP(&foreignKey, "foreign", "f", false, "是否导出外键关联")
|
||||
rootCmd.MarkFlagRequired("foreign")
|
||||
|
||||
rootCmd.Flags().IntVar(&mysqlInfo.Port, "port", 3306, "端口号")
|
||||
}
|
||||
|
||||
@@ -102,4 +106,8 @@ func MergeMysqlDbInfo() {
|
||||
if singularTable {
|
||||
config.SetSingularTable(singularTable)
|
||||
}
|
||||
|
||||
if foreignKey {
|
||||
config.SetForeignKey(foreignKey)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ import "fmt"
|
||||
|
||||
// Config custom config struct
|
||||
type Config struct {
|
||||
CfgBase
|
||||
MySQLInfo MysqlDbInfo `toml:"mysql_info"`
|
||||
OutDir string `toml:"out_dir"`
|
||||
Simple bool `toml:"simple"`
|
||||
IsJSONTag bool `toml:"isJsonTag"`
|
||||
SingularTable bool `toml:"singular_table"`
|
||||
CfgBase `yaml:"base"`
|
||||
MySQLInfo MysqlDbInfo `yaml:"mysql_info"`
|
||||
OutDir string `yaml:"out_dir"`
|
||||
Simple bool `yaml:"simple"`
|
||||
IsJSONTag bool `yaml:"is_json_tag"`
|
||||
SingularTable bool `yaml:"singular_table"`
|
||||
IsForeignKey bool `yaml:"is_foreign_key"`
|
||||
}
|
||||
|
||||
// MysqlDbInfo mysql database information. mysql 数据库信息
|
||||
@@ -71,3 +72,13 @@ func GetSimple() bool {
|
||||
func GetIsJSONTag() bool {
|
||||
return _map.IsJSONTag
|
||||
}
|
||||
|
||||
// GetIsForeignKey if is foreign key
|
||||
func GetIsForeignKey() bool {
|
||||
return _map.IsForeignKey
|
||||
}
|
||||
|
||||
// SetForeignKey Set if is foreign key.设置是否外键关联
|
||||
func SetForeignKey(b bool) {
|
||||
_map.IsForeignKey = b
|
||||
}
|
||||
|
||||
@@ -2,20 +2,20 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/xxjwxc/public/dev"
|
||||
"github.com/xxjwxc/public/tools"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// CfgBase base config struct
|
||||
type CfgBase struct {
|
||||
SerialNumber string `json:"serial_number" toml:"serial_number"` // version.版本号
|
||||
ServiceName string `json:"service_name" toml:"service_name"` // service name .service名字
|
||||
ServiceDisplayname string `json:"service_displayname" toml:"service_displayname"` // display name .显示名
|
||||
SerciceDesc string `json:"sercice_desc" toml:"sercice_desc"` // sercice desc .service描述
|
||||
IsDev bool `json:"is_dev" toml:"is_dev"` // Is it a development version?是否是开发版本
|
||||
SerialNumber string `json:"serial_number" yaml:"serial_number"` // version.版本号
|
||||
ServiceName string `json:"service_name" yaml:"service_name"` // service name .service名字
|
||||
ServiceDisplayname string `json:"service_displayname" yaml:"service_displayname"` // display name .显示名
|
||||
SerciceDesc string `json:"sercice_desc" yaml:"sercice_desc"` // sercice desc .service描述
|
||||
IsDev bool `json:"is_dev" yaml:"is_dev"` // Is it a development version?是否是开发版本
|
||||
}
|
||||
|
||||
var _map = Config{}
|
||||
@@ -27,7 +27,7 @@ func init() {
|
||||
|
||||
func onInit() {
|
||||
path := tools.GetModelPath()
|
||||
err := InitFile(path + "/config.toml")
|
||||
err := InitFile(path + "/config.yml")
|
||||
if err != nil {
|
||||
fmt.Println("InitFile: ", err.Error())
|
||||
return
|
||||
@@ -36,7 +36,11 @@ func onInit() {
|
||||
|
||||
// InitFile default value from file .
|
||||
func InitFile(filename string) error {
|
||||
if _, err := toml.DecodeFile(filename, &_map); err != nil {
|
||||
bs, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := yaml.Unmarshal(bs, &_map); err != nil {
|
||||
fmt.Println("read toml error: ", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -7,6 +7,23 @@ import (
|
||||
|
||||
const (
|
||||
testFile = `
|
||||
serial_number : "1.0" #版本号
|
||||
service_name : #服务名
|
||||
service_displayname : #服务显示名
|
||||
sercice_desc : #服务描述
|
||||
is_dev : false # 是否开发者模式
|
||||
out_dir : ./db # 输出目录
|
||||
singular_table : false # 单表模式:true:禁用表名复数,false:采用表明复数 参考:gorm.SingularTable
|
||||
simple : true #简单输出
|
||||
isJsonTag : true #是否打json标记
|
||||
mysql_info:
|
||||
host : 127.0.0.1
|
||||
port : 3306
|
||||
username : root
|
||||
password : qwer
|
||||
database : oauth_db
|
||||
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
|
||||
@@ -37,13 +37,16 @@ type TabInfo struct {
|
||||
// ColumusInfo Columus list .表列信息
|
||||
type ColumusInfo struct {
|
||||
BaseInfo
|
||||
Type string // Type.类型标记
|
||||
//Index string // index or unique_index or ''
|
||||
Index []KList // index list.index列表
|
||||
IsNull bool // null if db is set null
|
||||
Type string // Type.类型标记
|
||||
Index []KList // index list.index列表
|
||||
IsNull bool // null if db is set null
|
||||
ForeignKeyList []ForeignKey // Foreign key list . 表的外键信息
|
||||
}
|
||||
|
||||
//
|
||||
// Tags map[string][]string // tages.标记
|
||||
// ForeignKey Foreign key of db info . 表的外键信息
|
||||
type ForeignKey struct {
|
||||
TableName string // Affected tables . 该索引受影响的表
|
||||
ColumnName string // Which column of the affected table.该索引受影响的表的哪一列
|
||||
}
|
||||
|
||||
// KList database index /unique_index list.数据库index /unique_index 列表
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package genmysql
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/xxjwxc/gormt/data/view/model"
|
||||
)
|
||||
|
||||
// filterModel filter.过滤 gorm.Model
|
||||
func filterModel(list *[]genColumns) bool {
|
||||
@@ -25,3 +29,15 @@ func filterModel(list *[]genColumns) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// fixForeignKey fix foreign key.过滤外键
|
||||
func fixForeignKey(list []genForeignKey, columuName string, result *[]model.ForeignKey) {
|
||||
for _, v := range list {
|
||||
if strings.EqualFold(v.ColumnName, columuName) { // find it .找到了
|
||||
*result = append(*result, model.ForeignKey{
|
||||
TableName: v.ReferencedTableName,
|
||||
ColumnName: v.ReferencedColumnName,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,3 +14,15 @@ type genColumns struct {
|
||||
Desc string `gorm:"column:Comment"`
|
||||
Null string `gorm:"column:Null"`
|
||||
}
|
||||
|
||||
//select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
// where table_schema ='matrix' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'credit_card' ;
|
||||
// genForeignKey Foreign key of db info . 表的外键信息
|
||||
type genForeignKey struct {
|
||||
TableSchema string `gorm:"column:table_schema"` // Database of columns.列所在的数据库
|
||||
TableName string `gorm:"column:table_name"` // Data table of column.列所在的数据表
|
||||
ColumnName string `gorm:"column:column_name"` // Column names.列名
|
||||
ReferencedTableSchema string `gorm:"column:referenced_table_schema"` // The database where the index is located.该索引所在的数据库
|
||||
ReferencedTableName string `gorm:"column:referenced_table_name"` // Affected tables . 该索引受影响的表
|
||||
ReferencedColumnName string `gorm:"column:referenced_column_name"` // Which column of the affected table.该索引受影响的表的哪一列
|
||||
}
|
||||
|
||||
@@ -105,6 +105,12 @@ func getTableElement(orm *mysqldb.MySqlDB, tab string) (el []model.ColumusInfo)
|
||||
}
|
||||
// -----------------end
|
||||
|
||||
// ForeignKey
|
||||
var foreignKeyList []genForeignKey
|
||||
orm.Raw(`select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
where table_schema = ? AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = ? `, config.GetMysqlDbInfo().Database, tab).Find(&foreignKeyList)
|
||||
// ------------------end
|
||||
|
||||
for _, v := range list {
|
||||
var tmp model.ColumusInfo
|
||||
tmp.Name = v.Field
|
||||
@@ -138,6 +144,10 @@ func getTableElement(orm *mysqldb.MySqlDB, tab string) (el []model.ColumusInfo)
|
||||
}
|
||||
|
||||
tmp.IsNull = strings.EqualFold(v.Null, "YES")
|
||||
|
||||
// ForeignKey
|
||||
fixForeignKey(foreignKeyList, tmp.Name, &tmp.ForeignKeyList)
|
||||
// -----------------end
|
||||
el = append(el, tmp)
|
||||
}
|
||||
return
|
||||
|
||||
@@ -7,15 +7,26 @@ import (
|
||||
"github.com/xxjwxc/gormt/data/view/genstruct"
|
||||
)
|
||||
|
||||
type _Model struct {
|
||||
info DBInfo
|
||||
}
|
||||
|
||||
// Generate build code string.生成代码
|
||||
func Generate(info DBInfo) string {
|
||||
m := _Model{
|
||||
info: info,
|
||||
}
|
||||
return m.generate()
|
||||
}
|
||||
|
||||
func (m *_Model) generate() string {
|
||||
var pkg genstruct.GenPackage
|
||||
pkg.SetPackage(info.PackageName) //package name
|
||||
for _, tab := range info.TabList {
|
||||
pkg.SetPackage(m.info.PackageName) //package name
|
||||
for _, tab := range m.info.TabList {
|
||||
var sct genstruct.GenStruct
|
||||
sct.SetStructName(getCamelName(tab.Name)) // Big hump.大驼峰
|
||||
sct.SetNotes(tab.Notes)
|
||||
sct.AddElement(getTableElement(tab.Em)...) // build element.构造元素
|
||||
sct.AddElement(m.genTableElement(tab.Em)...) // build element.构造元素
|
||||
sct.SetCreatTableStr(tab.SQLBuildStr)
|
||||
pkg.AddStruct(sct)
|
||||
}
|
||||
@@ -23,9 +34,9 @@ func Generate(info DBInfo) string {
|
||||
return pkg.Generate()
|
||||
}
|
||||
|
||||
// getTableElement Get table columns and comments.获取表列及注释
|
||||
func getTableElement(tabs []ColumusInfo) (el []genstruct.GenElement) {
|
||||
for _, v := range tabs {
|
||||
// genTableElement Get table columns and comments.获取表列及注释
|
||||
func (m *_Model) genTableElement(cols []ColumusInfo) (el []genstruct.GenElement) {
|
||||
for _, v := range cols {
|
||||
var tmp genstruct.GenElement
|
||||
if strings.EqualFold(v.Type, "gorm.Model") { // gorm model
|
||||
tmp.SetType(v.Type) //
|
||||
@@ -74,7 +85,91 @@ func getTableElement(tabs []ColumusInfo) (el []genstruct.GenElement) {
|
||||
}
|
||||
}
|
||||
el = append(el, tmp)
|
||||
|
||||
// ForeignKey
|
||||
if config.GetIsForeignKey() && len(v.ForeignKeyList) > 0 {
|
||||
fklist := m.genForeignKey(v)
|
||||
if len(fklist) > 0 {
|
||||
el = append(el, fklist...)
|
||||
}
|
||||
}
|
||||
// -----------end
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// genForeignKey Get information about foreign key of table column.获取表列外键相关信息
|
||||
func (m *_Model) genForeignKey(col ColumusInfo) (fklist []genstruct.GenElement) {
|
||||
for _, v := range col.ForeignKeyList {
|
||||
isMulti, isFind, notes := m.getColumusKeyMulti(v.TableName, v.ColumnName)
|
||||
if isFind {
|
||||
var tmp genstruct.GenElement
|
||||
tmp.SetNotes(notes)
|
||||
if isMulti {
|
||||
tmp.SetName(getCamelName(v.TableName) + "List")
|
||||
tmp.SetType("[]" + getCamelName(v.TableName))
|
||||
} else {
|
||||
tmp.SetName(getCamelName(v.TableName))
|
||||
tmp.SetType(getCamelName(v.TableName))
|
||||
}
|
||||
|
||||
tmp.AddTag(_tagGorm, "association_foreignkey:"+col.Name)
|
||||
tmp.AddTag(_tagGorm, "foreignkey:"+v.ColumnName)
|
||||
|
||||
// json tag
|
||||
if config.GetIsJSONTag() {
|
||||
tmp.AddTag(_tagJSON, v.TableName+"_list")
|
||||
}
|
||||
|
||||
fklist = append(fklist, tmp)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m *_Model) getColumusKeyMulti(tableName, col string) (isMulti bool, isFind bool, notes string) {
|
||||
var haveGomod bool
|
||||
for _, v := range m.info.TabList {
|
||||
if strings.EqualFold(v.Name, tableName) {
|
||||
for _, v1 := range v.Em {
|
||||
if strings.EqualFold(v1.Name, col) {
|
||||
for _, v2 := range v1.Index {
|
||||
switch v2.Key {
|
||||
case ColumusKeyPrimary, ColumusKeyUnique, ColumusKeyUniqueIndex: // primary key unique key . 主键,唯一索引
|
||||
{
|
||||
return false, true, v.Notes
|
||||
}
|
||||
// case ColumusKeyIndex: // index key. 复合索引
|
||||
// {
|
||||
// isMulti = true
|
||||
// }
|
||||
}
|
||||
}
|
||||
return true, true, v.Notes
|
||||
} else if strings.EqualFold(v1.Type, "gorm.Model") {
|
||||
haveGomod = true
|
||||
notes = v.Notes
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// default gorm.Model
|
||||
if haveGomod {
|
||||
if strings.EqualFold(col, "id") {
|
||||
return false, true, notes
|
||||
}
|
||||
|
||||
if strings.EqualFold(col, "created_at") ||
|
||||
strings.EqualFold(col, "updated_at") ||
|
||||
strings.EqualFold(col, "deleted_at") {
|
||||
return true, true, notes
|
||||
}
|
||||
}
|
||||
|
||||
return false, false, ""
|
||||
// -----------------end
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user