feat(ReverseEngine):初始化工程
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
package reverse
|
||||
|
||||
import (
|
||||
"ReverseEngine/entity"
|
||||
"ReverseEngine/imp"
|
||||
"ReverseEngine/static"
|
||||
"ReverseEngine/support"
|
||||
"ReverseEngine/util"
|
||||
"bufio"
|
||||
"database/sql"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"gopkg.in/ini.v1"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
//数据库到实体映射 可在config.ini中配置
|
||||
tm = make(map[string]string)
|
||||
|
||||
//通用配置 可在config.ini中配置
|
||||
def = "string" //默认的映射类型
|
||||
tagKey = "xorm" //tag的key
|
||||
suffix = ".go" //文件后缀
|
||||
cover = true //存在文件是否进行覆盖,只有配置为false的时候不会覆盖,其他默认为true
|
||||
|
||||
//数据库配置 可在config.ini中配置 格式是:”用户名:密码@tcp(IP:端口)/数据库?charset=utf8”
|
||||
username = "你的mysql连接账号"
|
||||
password = "你的连接密码"
|
||||
tcp = "@tcp"
|
||||
ip = "你的地址"
|
||||
port = "3306"
|
||||
database = "你的数据库" //这个是我的数据库
|
||||
charset = "utf8mb4&parseTime=True&loc=Local"
|
||||
connMaxLifeTime = 100
|
||||
maxIdleConns = 10
|
||||
|
||||
//校验、数据库连接实现类
|
||||
cg imp.ContentGenerate
|
||||
dbc imp.DbConnection
|
||||
rc imp.ReverseCheck
|
||||
)
|
||||
|
||||
//---------------------------------------初始化,策略配置,规则校验-----------------------------------------
|
||||
|
||||
type DataReverseEngine struct {
|
||||
}
|
||||
|
||||
func NewEngine() *DataReverseEngine {
|
||||
return &DataReverseEngine{}
|
||||
}
|
||||
|
||||
//创建初始化 --加载配置信息等
|
||||
func init() {
|
||||
cfg := loadIniCfg() //获取ini配置文件的对象
|
||||
if nil == cfg {
|
||||
panic("配置文件 config.ini配置错误,请检查")
|
||||
return
|
||||
}
|
||||
loadCommonConfig(cfg) //加载通用配置
|
||||
loadDataBaseConfig(cfg) //加载数据库配置
|
||||
loadTypeMappingConfig(cfg) //加载类型映射配置
|
||||
rc = &support.CheckSupport{} //校验支持
|
||||
dbc = &support.DbSupport{} //数据库支持
|
||||
cg = &support.FileContentSupport{} //文本拼接支持
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
重写自己的文件类型定义实现
|
||||
*/
|
||||
func (*DataReverseEngine) SetContentGenerate(face imp.ContentGenerate) {
|
||||
cg = face
|
||||
}
|
||||
|
||||
/*
|
||||
重写自己的数据库连接工具
|
||||
*/
|
||||
func (*DataReverseEngine) SetDbConnection(face imp.DbConnection) {
|
||||
dbc = face
|
||||
}
|
||||
|
||||
/*
|
||||
重写自己的校验规则
|
||||
*/
|
||||
func (*DataReverseEngine) SetReverseCheck(face imp.ReverseCheck) {
|
||||
rc = face
|
||||
}
|
||||
|
||||
func checkError(err error, s string) {
|
||||
if err != nil {
|
||||
panic(s + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------逆向工程---------------------------------
|
||||
|
||||
/*
|
||||
数据库逆向工程
|
||||
tableName:表名
|
||||
path:创建目录的相对路径(右键选中文件夹,点击relative path得到的路径)
|
||||
*/
|
||||
func (r *DataReverseEngine) SimpleEngineer(tableName string, path string) {
|
||||
r.Engineer(database, tableName, path, cover)
|
||||
}
|
||||
|
||||
/*
|
||||
数据库逆向工程
|
||||
tableName:表名
|
||||
path:创建目录的相对路径(右键选中文件夹,点击relative path得到的路径)
|
||||
cover:如果已经存在改文件是否进行覆盖
|
||||
*/
|
||||
func (r *DataReverseEngine) SimEngineer(tableName string, path string, cover bool) {
|
||||
r.Engineer(database, tableName, path, cover)
|
||||
}
|
||||
|
||||
/*
|
||||
数据库逆向工程
|
||||
dbName:数据库名称
|
||||
tableName:表名
|
||||
path:创建目录的相对路径(右键选中文件夹,点击relative path得到的路径)
|
||||
cover:如果已经存在改文件是否进行覆盖
|
||||
*/
|
||||
func (*DataReverseEngine) Engineer(dbName string, tableName string, path string, cover bool) {
|
||||
//tableName = strings.Title(tableName) //tableName进行首字母大写
|
||||
if !rc.CheckFileDir(path, tableName, cover) { //进行通用校验
|
||||
return
|
||||
}
|
||||
dbPath := strings.Join([]string{username, ":", password, tcp, "(", ip, ":", port, ")/", database, "?", "charset=", charset}, "")
|
||||
db := dbc.CreateDbConnection(dbPath, maxIdleConns, connMaxLifeTime) //连接数据库--可配置连接不同的数据库
|
||||
if db == nil {
|
||||
log.Println("数据库连接失败,程序终止")
|
||||
return
|
||||
}
|
||||
//校验对应的数据库表是否存在
|
||||
if rc.CheckTableExist(dbName, tableName, db) {
|
||||
dbReverse(path, tableName, dbName, db)
|
||||
return
|
||||
}
|
||||
log.Println("数据库表不存在:", tableName) //不存在的话打印日志返回
|
||||
}
|
||||
|
||||
func dbReverse(path string, tableName string, dbName string, db *sql.DB) {
|
||||
file, result := util.CreateNeedOpenFile(util.GenerateFilePath(path, tableName, static.Splice, suffix))
|
||||
if !result {
|
||||
return
|
||||
}
|
||||
cms := util.FindColumnMessage(dbName, tableName, db) //查询数据库表字段信息
|
||||
dErr := db.Close() //关闭数据库连接
|
||||
checkError(dErr, "数据库关闭失败:")
|
||||
if nil == cms {
|
||||
log.Println("没有查到数据库字段信息略过")
|
||||
}
|
||||
fms, hasTime := buildFieldMessage(cms) //创建字段名和类型的映射
|
||||
w := bufio.NewWriter(file) //进行文件的操作
|
||||
content := cg.GenerateFileContent(path, tableName, fms, hasTime, tagKey) //拼go文件
|
||||
_, err := w.WriteString(content)
|
||||
checkError(err, "写入出错了:")
|
||||
fErr, cErr := w.Flush(), file.Close()
|
||||
|
||||
checkError(fErr, "文件写入出错了,flush错误:")
|
||||
checkError(cErr, "文件写入出错了,close错误:")
|
||||
}
|
||||
|
||||
func buildFieldMessage(cms []entity.ColumnMessage) ([]entity.FieldMessage, bool) {
|
||||
var fms []entity.FieldMessage
|
||||
hasTime := false
|
||||
|
||||
for _, cm := range cms {
|
||||
fm := &entity.FieldMessage{
|
||||
FiledName: cm.Field, //字段名称
|
||||
FieldType: typeMapping(cm.Type, &hasTime), //字段类型,进行映射
|
||||
OriginType: cm.Type, //数据库原始类型
|
||||
IsKey: cm.IsKey(), //是否主键
|
||||
TagKey: tagKey, //tag的key值,这边先写死,正常应该是可配
|
||||
Comment: cm.GetComment(), //注释信息
|
||||
Default: cm.GetDefault(), //默认值信息
|
||||
CanNull: cm.CanNull(), //是否可以为空
|
||||
}
|
||||
|
||||
fms = append(fms, *fm)
|
||||
}
|
||||
|
||||
return fms, hasTime
|
||||
}
|
||||
|
||||
func typeMapping(t string, has *bool) string {
|
||||
rt := strings.Split(t, "(")[0] //需要把类型后面的([长度])去掉
|
||||
value, ok := tm[rt]
|
||||
if ok {
|
||||
if value == static.TimeT {
|
||||
*has = true
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
return def
|
||||
}
|
||||
|
||||
//-----------------------------------读取和属性设置-----------------------------
|
||||
func loadIniCfg() *ini.File {
|
||||
cfg, err := ini.Load(static.IniAddress)
|
||||
if err != nil {
|
||||
log.Println("读取失败使用原始配置", err)
|
||||
os.Exit(1)
|
||||
return nil
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
func loadDataBaseConfig(cfg *ini.File) {
|
||||
if len(cfg.Section(static.DataBase).Keys()) == 0 {
|
||||
log.Println("配置区间为空,采用数据库配置通用配置")
|
||||
return
|
||||
}
|
||||
util.GenerateConfig("username", username, cfg.Section(static.DataBase))
|
||||
util.GenerateConfig("password", password, cfg.Section(static.DataBase))
|
||||
util.GenerateConfig("tcp", tcp, cfg.Section(static.DataBase))
|
||||
util.GenerateConfig("ip", ip, cfg.Section(static.DataBase))
|
||||
util.GenerateConfig("port", port, cfg.Section(static.DataBase))
|
||||
util.GenerateConfig("database", database, cfg.Section(static.DataBase))
|
||||
util.GenerateConfig("charset", charset, cfg.Section(static.DataBase))
|
||||
util.GenerateConfigInt("connMaxLifeTime", connMaxLifeTime, cfg.Section(static.DataBase))
|
||||
util.GenerateConfigInt("maxIdleConns", maxIdleConns, cfg.Section(static.DataBase))
|
||||
|
||||
}
|
||||
|
||||
func loadCommonConfig(cfg *ini.File) {
|
||||
if len(cfg.Section(static.Common).Keys()) == 0 {
|
||||
log.Println("配置区间为空,采用通用配置")
|
||||
return
|
||||
}
|
||||
util.GenerateConfig("def", def, cfg.Section(static.Common)) //默认的映射类型
|
||||
util.GenerateConfig("tagKey", tagKey, cfg.Section(static.Common)) //tag的key
|
||||
util.GenerateConfig("suffix", suffix, cfg.Section(static.Common)) //文件后缀
|
||||
util.GenerateConfigBool("cover", &cover, cfg.Section(static.Common)) //存在文件是否进行覆盖,只有配置为false的时候不会覆盖,其他默认为true
|
||||
}
|
||||
|
||||
func defaultTypeMappingConfig() {
|
||||
tm["double"] = "float64"
|
||||
tm["float"] = "float64"
|
||||
tm["int"] = "int"
|
||||
tm["tinyint"] = "int"
|
||||
tm["bigint"] = "int"
|
||||
tm["time"] = "time.Time"
|
||||
tm["timestamp"] = "time.Time"
|
||||
tm["date"] = "time.Time"
|
||||
tm["dateTime"] = "time.Time"
|
||||
}
|
||||
|
||||
func loadTypeMappingConfig(cfg *ini.File) {
|
||||
if len(cfg.Section(static.MapType).Keys()) == 0 {
|
||||
defaultTypeMappingConfig()
|
||||
log.Println("配置区间为空,采用类型映射通用配置")
|
||||
return
|
||||
}
|
||||
|
||||
for _, k := range cfg.Section(static.MapType).Keys() {
|
||||
if k.Name() != "" {
|
||||
tm[k.Name()] = k.Value()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
[database] //数据库配置
|
||||
username = 你的mysql连接账号
|
||||
password = 你的连接密码
|
||||
tcp = @tcp
|
||||
ip = 你的地址
|
||||
port = 3306
|
||||
database = 你的数据库名
|
||||
charset = utf8mb4&parseTime=True&loc=Local
|
||||
connMaxLifeTime = 100
|
||||
maxIdleConns = 10
|
||||
|
||||
[common] //通用配置
|
||||
def = string //默认的映射类型
|
||||
tagKey = xorm //tag的key
|
||||
suffix = .go //文件后缀
|
||||
cover = true //存在文件是否进行覆盖,只有配置为false的时候不会覆盖,其他默认为true
|
||||
|
||||
|
||||
[type_mapping] //类型映射
|
||||
double = float64
|
||||
float = float64
|
||||
int = int
|
||||
tinyint = int
|
||||
bigint = int
|
||||
time = time.Time
|
||||
timestamp = time.Time
|
||||
date = time.Time
|
||||
datetime = time.Time
|
||||
Reference in New Issue
Block a user