├── .coveralls.yml ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── go.yml ├── .gitignore ├── .travis.yml ├── FUNDING.yml ├── LICENSE ├── Makefile ├── README.md ├── README_zh_cn.md ├── config.yml ├── data ├── cmd │ └── cmd.go ├── config │ ├── MyIni.go │ ├── common.go │ └── test_def.go ├── dlg │ ├── cmd_darwin.go │ ├── cmd_linux.go │ ├── cmd_windows.go │ ├── common.go │ ├── cui.go │ ├── def.go │ ├── i18n.go │ └── mycui.go └── view │ ├── cnf │ └── def.go │ ├── generate │ ├── def.go │ └── generate.go │ ├── genfunc │ ├── def.go │ ├── genfunc.go │ ├── genfunc_test.go │ └── model │ │ ├── gen.base.go │ │ ├── matrix.gen.account.go │ │ ├── matrix.gen.user.go │ │ ├── matrix.go │ │ └── matrix.sql │ ├── genstruct │ ├── common.go │ └── def.go │ ├── gtools │ ├── gtools.go │ └── gtools_test.go │ └── model │ ├── common.go │ ├── def.go │ ├── def_ifs.go │ ├── gencnf │ └── gencnf.go │ ├── genmssql │ ├── common.go │ ├── def.go │ └── genmssql.go │ ├── genmysql │ ├── common.go │ ├── def.go │ └── genmysql.go │ ├── gensqlite │ ├── common.go │ ├── def.go │ └── gensqlite.go │ ├── model.go │ └── model_test.go ├── doc ├── export.md ├── export_cn.md ├── func.md └── func_cn.md ├── go.mod ├── go.sum ├── gogenerate.go ├── image ├── .DS_Store └── gormt │ ├── 1.png │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── out.gif │ ├── ui_cn.gif │ └── ui_en.gif ├── main.go ├── main_test.go └── sql.yml /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name:travis-pro 2 | repo_token:0LTKdJPyx19srGcw0Ef8URUlG8fE4K2sa -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [xxjwxc] 2 | custom: ["https://www.paypal.me/xxjwxc"] 3 | patreon: xxjwxc -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | on: [push] 3 | jobs: 4 | 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | steps: 9 | 10 | - name: Set up Go 1.13 11 | uses: actions/setup-go@v1 12 | with: 13 | go-version: 1.13 14 | id: go 15 | 16 | - name: Check out code into the Go module directory 17 | uses: actions/checkout@v1 18 | 19 | - name: Get dependencies 20 | run: | 21 | go get -v -t -d ./... 22 | if [ -f Gopkg.toml ]; then 23 | curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh 24 | dep ensure 25 | fi 26 | 27 | - name: Build 28 | run: go build -v . 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | db/oauth_db.go 3 | .vscode/settings.json 4 | /.idea 5 | /err 6 | /model 7 | gormt.yml 8 | gormt 9 | /vendor 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.13.x 4 | - master 5 | 6 | go_import_path: github.com/xxjwxc/gormt 7 | 8 | before_install: 9 | - go get -t -v ./... 10 | 11 | script: 12 | - go test -race -coverprofile=coverage.txt -covermode=atomic 13 | 14 | after_success: 15 | - bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 xiaojunxie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: # 构建 2 | make tar 3 | windows: 4 | CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o gormt.exe main.go 5 | mac: 6 | CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o gormt main.go 7 | linux: 8 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o gormt main.go 9 | tar: # 打包 10 | CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o gormt.exe main.go 11 | tar czvf gormt_windows.zip gormt.exe config.yml 12 | CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build -o gormt main.go 13 | tar czvf gormt_mac.zip gormt config.yml 14 | CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o gormt main.go 15 | tar czvf gormt_linux.zip gormt config.yml 16 | clear: 17 | test ! -d model/ || rm -rf model/* 18 | test ! -d err/ || rm -rf err/ 19 | test ! -f gormt || rm gormt 20 | test ! -f gormt.exe || rm gormt.exe 21 | test ! -f gormt_linux.zip || rm gormt_linux.zip 22 | test ! -f gormt_mac.zip || rm gormt_mac.zip 23 | test ! -f gormt_windows.zip || rm gormt_windows.zip 24 | master: 25 | go get -u github.com/xxjwxc/public@master 26 | go get -u gorm.io/gorm@master 27 | go get -u gorm.io/driver/sqlserver@master 28 | go get -u gorm.io/driver/sqlite@master -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/xxjwxc/gormt.svg?branch=master)](https://travis-ci.org/xxjwxc/gormt) 2 | [![Go Report Card](https://goreportcard.com/badge/github.com/xxjwxc/gormt)](https://goreportcard.com/report/github.com/xxjwxc/gormt) 3 | [![GoDoc](https://godoc.org/github.com/xxjwxc/gormt?status.svg)](https://godoc.org/github.com/xxjwxc/gormt) 4 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) 5 | Featured|HelloGitHub 6 | 7 | ## [中文文档](README_zh_cn.md) 8 | 9 | ### mysql database to golang struct conversion tools base on [gorm(v1/v2)](https://github.com/go-gorm/gorm),You can automatically generate golang sturct from mysql database. big Camel-Case Name Rule, JSON tag. 10 | 11 | 12 | 13 | ## gui support 14 | 15 | ![show](/image/gormt/ui_en.gif) 16 | 17 | ``` 18 | ./gormt -g=true 19 | ``` 20 | 21 | ## cmd support 22 | 23 | ![show](/image/gormt/out.gif) 24 | ``` 25 | ./gormt -g=false 26 | ``` 27 | 28 | ## install 29 | 30 | ``` 31 | go get -u -v github.com/xxjwxc/gormt@latest 32 | ``` 33 | 34 | or: [Dowloading](https://github.com/xxjwxc/gormt/releases) 35 | 36 | -------- 37 | 38 | ## 1. Configure default configuration items through the current directory config.yml file 39 | note: for latest version of config format, please check /data/config/MyIni.go 40 | ```yml 41 | out_dir : "./model" # out dir 42 | url_tag : json # web url tag(json,db(https://github.com/google/go-querystring)) 43 | language : # language(English,中 文) 44 | db_tag : gorm # DB tag(gorm,db) 45 | simple : false #simple output 46 | is_out_sql : false # Whether to output sql 47 | is_out_func : true # Whether to output function 48 | is_foreign_key : true # Whether to mark foreign key or not 49 | is_gui : false # Whether to operate on gui 50 | is_table_name : false # Whether to out GetTableName/column function 51 | is_null_to_point : false # database is 'DEFAULT NULL' then set element type as point 52 | is_web_tag: false 53 | is_web_tag_pk_hidden: false 54 | table_prefix: "" #table prefix 55 | table_names: "" # Specified table generation, multiple tables with , separated 56 | is_column_name: true # Whether to generate column names 57 | is_out_file_by_table_name: false # Whether to generate multiple models based on table names 58 | db_info : 59 | host : "127.0.0.1" 60 | port : 3306 61 | username : "root" 62 | password : "qwer" 63 | database : "oauth_db" 64 | type: 0 # database type (0:mysql , 1:sqlite , 2:mssql) 65 | self_type_define: # Custom data type mapping 66 | datetime: time.Time 67 | date: time.Time 68 | out_file_name: "" # Custom build file name 69 | web_tag_type: 0 # json tag 0: Small Camel-Case 1: _ 70 | 71 | ``` 72 | ## 2. get help 73 | ``` 74 | ./gormt --help 75 | or 76 | ./gormt -h 77 | 78 | ------------------------------------------------------- 79 | base on gorm tools for mysql database to golang struct 80 | 81 | Usage: 82 | main [flags] 83 | 84 | Flags: 85 | -d, --database string 数据库名 86 | -f, --foreign 是否导出外键关联 87 | -F, --fun 是否导出函数 88 | -g, --gui 是否ui显示模式 89 | -h, --help help for main 90 | -H, --host string 数据库地址.(注意-H为大写) 91 | -o, --outdir string 输出目录 92 | -p, --password string 密码. 93 | --port int 端口号 (default 3306) 94 | -s, --singular 是否禁用表名复数 95 | -b, --table_names string 表名称 96 | -l, --url string url标签(json,url) 97 | -u, --user string 用户名. 98 | 99 | ``` 100 | ## 3. Can be updated configuration items using command line tools 101 | ``` 102 | ./gormt -H=127.0.0.1 -d=oauth_db -p=qwer -u=root --port=3306 -F=true 103 | ``` 104 | 105 | ## 4. Support for gorm attributes 106 | 107 | - Database tables, column field annotation support 108 | - json tag json tag output 109 | - gorm.Model [Support export gorm.model>>>](doc/export.md) 110 | - PRIMARY_KEY Specifies column as primary key 111 | - UNIQUE Specifies column as unique 112 | - NOT NULL Specifies column as NOT NULL 113 | - INDEX Create index with or without name, same name creates composite indexes 114 | - UNIQUE_INDEX Like INDEX, create unique index 115 | - Support foreign key related properties [Support export gorm.model>>>](doc/export.md) 116 | - Support function export (foreign key, association, index , unique and more)[Support export function >>>](https://github.com/xxjwxc/gormt/blob/master/data/view/genfunc/genfunc_test.go) 117 | - model.Condition{} sql link 118 | 119 | ### You can enrich data types in [def](data/view/cnf/def.go) 120 | 121 | ## 5. Demonstration 122 | 123 | - sql: 124 | ``` 125 | CREATE TABLE `user_account_tbl` ( 126 | `id` int(11) NOT NULL AUTO_INCREMENT, 127 | `account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 128 | `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 129 | `account_type` int(11) NOT NULL DEFAULT '0' COMMENT '帐号类型:0手机号,1邮件', 130 | `app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id', 131 | `user_info_tbl_id` int(11) NOT NULL, 132 | `reg_time` datetime DEFAULT NULL, 133 | `reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 134 | `bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 135 | `describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 136 | PRIMARY KEY (`id`) USING BTREE, 137 | UNIQUE KEY `account` (`account`) USING BTREE, 138 | KEY `user_info_id` (`user_info_tbl_id`) USING BTREE, 139 | CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT 140 | ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户账号' 141 | ``` 142 | 143 | ###### --->Derived results 144 | 145 | ``` 146 | // UserAccountTbl 用户账号 147 | type UserAccountTbl struct { 148 | ID int `gorm:"primary_key"` 149 | Account string `gorm:"unique"` 150 | Password string 151 | AccountType int // 帐号类型:0手机号,1邮件 152 | AppKey string // authbucket_oauth2_client表的id 153 | UserInfoTblID int `gorm:"index"` 154 | UserInfoTbl UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息 155 | RegTime time.Time 156 | RegIP string 157 | BundleID string 158 | Describ string 159 | } 160 | ``` 161 | 162 | ### [more>>>](doc/export.md) 163 | 164 | ## 6. support func export 165 | ### The exported function is only the auxiliary class function of Gorm, and calls Gorm completely 166 | ``` 167 | // FetchByPrimaryKey primary or index 获取唯一内容 168 | func (obj *_UserAccountTblMgr) FetchByPrimaryKey(ID int) (result UserAccountTbl, err error) { 169 | err = obj.DB.Table(obj.GetTableName()).Where("id = ?", ID).Find(&result).Error 170 | if err == nil && obj.isRelated { 171 | { 172 | var info UserInfoTbl // 用户信息 173 | err = obj.DB.Table("user_info_tbl").Where("id = ?", result.UserInfoTblID).Find(&info).Error 174 | if err != nil { 175 | return 176 | } 177 | result.UserInfoTbl = info 178 | } 179 | } 180 | 181 | return 182 | } 183 | 184 | ``` 185 | 186 | ### [more>>>](https://github.com/xxjwxc/gormt/tree/master/doc/func.md) 187 | ### [how to use call style>>>](https://github.com/xxjwxc/gormt/blob/master/data/view/genfunc/genfunc_test.go) 188 | 189 | ## 7. page 190 | ### [Use of paging query in gormt](https://xiaojujiang.blog.csdn.net/article/details/122315454?spm=1001.2014.3001.5502) 191 | 192 | ## 8. build 193 | ``` 194 | make windows 195 | make linux 196 | make mac 197 | ``` 198 | or 199 | 200 | ``` 201 | go generate 202 | ``` 203 | 204 | ### note : in windows not support utf-8 style . ASCALL model 205 | - Switch encoding mode 206 | ``` 207 | CHCP 65001 208 | ``` 209 | 210 | ### column notes default 211 | 212 | - Add a comment to the column starting with `[@gorm default:'test']` 213 | - example `[@gorm default:'test';->;<-:create]this is my notes` Indicates that the default value is 'test',can read/creat/write 214 | - Use of foreign key notes`[@fk tableName.columnName]this is my notes` Represents the 'columnName' column associated with the 'tableName' 215 | 216 | ## 9. one windows gui tools 217 | 218 | ![1](/image/gormt/1.png) 219 | 220 | ![2](/image/gormt/2.jpg) 221 | 222 | ![3](/image/gormt/3.jpg) 223 | 224 | ![4](/image/gormt/4.jpg) 225 | 226 | [Download](https://github.com/xxjwxc/gormt/releases/download/v0.3.8/v1.0.zip) 227 | 228 | 229 | 230 | - ###### [link](https://xxjwxc.github.io/post/gormtools/) 231 | 232 | ## Stargazers over time 233 | 234 | [![Stargazers over time](https://starchart.cc/xxjwxc/gormt.svg)](https://starchart.cc/xxjwxc/gormt) 235 | -------------------------------------------------------------------------------- /README_zh_cn.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/xxjwxc/gormt.svg?branch=master)](https://travis-ci.org/xxjwxc/gormt) 2 | [![Go Report Card](https://goreportcard.com/badge/github.com/xxjwxc/gormt)](https://goreportcard.com/report/github.com/xxjwxc/gormt) 3 | [![GoDoc](https://godoc.org/github.com/xxjwxc/gormt?status.svg)](https://godoc.org/github.com/xxjwxc/gormt) 4 | [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) 5 | 6 | # [gorm-tools](https://github.com/xxjwxc/gormt) 7 | 8 | -------- 9 | 10 | #### mysql数据库转 struct 工具,可以将mysql数据库自动生成golang sturct结构,带大驼峰命名规则。带json标签 11 | 12 | [English](README.md) 13 | 14 | ## 交互界面模式 15 | 16 | ![show](/image/gormt/ui_cn.gif) 17 | 18 | ``` 19 | ./gormt -g=true 20 | ``` 21 | 22 | ## 命令行模式 23 | 24 | ![show](/image/gormt/out.gif) 25 | ``` 26 | ./gormt -g=false 27 | ``` 28 | -------- 29 | 30 | ## 安装 31 | 32 | ``` 33 | go get -u -v github.com/xxjwxc/gormt@master 34 | ``` 35 | 36 | 或者: [下载地址](https://github.com/xxjwxc/gormt/releases) 37 | 38 | ## 1. 通过当前目录 config.yml 文件配置默认配置项 39 | 注意:最新的配置请参考 [MyIni.go](/data/config/MyIni.go), 或使用命令行工具默认生成的。 40 | 41 | ```yml 42 | base: 43 | is_dev: false 44 | out_dir: ./model # 输出目录 45 | url_tag: json # web url tag(json,db(https://github.com/google/go-querystring)) 46 | language: 中 文 # 语言(English,中 文) 47 | db_tag: gorm # 数据库标签(gorm,db) 48 | simple: false # 简单输出(默认gorm标签不输出) 49 | is_out_sql: false # 是否输出 sql 原信息 50 | is_out_func: true # 是否输出 快捷函数 51 | is_foreign_key: true # 是否导出外键关联 52 | is_gui: false # 是否ui模式显示 53 | is_table_name: false # 是否直接生成表名,列名 54 | is_null_to_point: false # 数据库默认 'DEFAULT NULL' 时设置结构为指针类型 55 | is_web_tag: false 56 | is_web_tag_pk_hidden: false 57 | table_prefix: "" #表前缀 58 | table_names: "" #指定表生成,多个表用,隔开 59 | is_column_name: true # 是否生成列名 60 | is_out_file_by_table_name: false # 是否根据表名生成多个model 61 | db_info: 62 | host : 127.0.0.1 63 | port : 3306 64 | username : root 65 | password : qwer 66 | database : oauth_db 67 | type: 0 # 数据库类型:0:mysql , 1:sqlite , 2:mssql 68 | self_type_define: # 自定义数据类型映射 69 | datetime: time.Time 70 | date: time.Time 71 | out_file_name: "" # 自定义生成文件名 72 | web_tag_type: 0 # json tag类型 0: 小驼峰 1: 下划线 73 | 74 | ``` 75 | 76 | ## 2. 可以使用命令行工具更新配置项 77 | 78 | ``` 79 | ./gormt -H=127.0.0.1 -d=oauth_db -p=qwer -u=root --port=3306 80 | ``` 81 | 命令行工具默认会生成`config.yml`, 具体位置为gormt 可执行文件所在目录。 82 | 可以通过 `which gormt` 查找所在目录。 83 | ## 3. 查看帮助 84 | 85 | ``` 86 | ./gormt --help 87 | or 88 | ./gormt -h 89 | 90 | ------------------------------------------------------- 91 | base on gorm tools for mysql database to golang struct 92 | 93 | Usage: 94 | main [flags] 95 | 96 | Flags: 97 | -d, --database string 数据库名 98 | -f, --foreign 是否导出外键关联 99 | -F, --fun 是否导出函数 100 | -g, --gui 是否ui显示模式 101 | -h, --help help for main 102 | -H, --host string 数据库地址.(注意-H为大写) 103 | -o, --outdir string 输出目录 104 | -p, --password string 密码. 105 | --port int 端口号 (default 3306) 106 | -s, --singular 是否禁用表名复数 107 | -b, --table_names string 表名称 108 | -l, --url string url标签(json,url) 109 | -u, --user string 用户名. 110 | 111 | ``` 112 | 113 | ## 4. 支持gorm 相关属性 114 | 115 | - 数据库表,列字段注释支持 116 | - json tag json标签输出 117 | - gorm.Model 基本模型 [支持gorm.Model模式导出>>>](https://github.com/xxjwxc/gormt/tree/master/doc/export_cn.md) 118 | - PRIMARY_KEY 将列指定为主键 119 | - UNIQUE 将列指定为唯一 120 | - NOT NULL 将列指定为非 NULL 121 | - INDEX 创建具有或不带名称的索引, 如果多个索引同名则创建复合索引 122 | - UNIQUE_INDEX 和 INDEX 类似,只不过创建的是唯一索引 123 | - 支持外键相关属性 [简单带外键模式导出>>>](https://github.com/xxjwxc/gormt/tree/master/doc/export_cn.md) 124 | - 支持函数导出(包括:外键,关联体,索引关...)[简单函数导出示例>>>](https://github.com/xxjwxc/gormt/blob/master/data/view/genfunc/genfunc_test.go) 125 | - 支持默认值default 126 | - model.Condition{} sql拼接 127 | 128 | ### 您可以在这里丰富数据映射类型 [def](data/view/cnf/def.go) 。 129 | 130 | ## 5. 示例展示 131 | sql: 132 | ``` 133 | CREATE TABLE `user_account_tbl` ( 134 | `id` int(11) NOT NULL AUTO_INCREMENT, 135 | `account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 136 | `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 137 | `account_type` int(11) NOT NULL DEFAULT '0' COMMENT '帐号类型:0手机号,1邮件', 138 | `app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id', 139 | `user_info_tbl_id` int(11) NOT NULL, 140 | `reg_time` datetime DEFAULT NULL, 141 | `reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 142 | `bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 143 | `describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 144 | PRIMARY KEY (`id`) USING BTREE, 145 | UNIQUE KEY `account` (`account`) USING BTREE, 146 | KEY `user_info_id` (`user_info_tbl_id`) USING BTREE, 147 | CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT 148 | ) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户账号' 149 | ``` 150 | 151 | ###### --->导出结果 152 | 153 | ``` 154 | // UserAccountTbl 用户账号 155 | type UserAccountTbl struct { 156 | ID int `gorm:"primary_key"` 157 | Account string `gorm:"unique"` 158 | Password string 159 | AccountType int // 帐号类型:0手机号,1邮件 160 | AppKey string // authbucket_oauth2_client表的id 161 | UserInfoTblID int `gorm:"index"` 162 | UserInfoTbl UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息 163 | RegTime time.Time 164 | RegIP string 165 | BundleID string 166 | Describ string 167 | } 168 | ``` 169 | 170 | ### [更多>>>](https://github.com/xxjwxc/gormt/tree/master/doc/export_cn.md) 171 | 172 | ## 6. 支持函数导出(导出函数只是 gorm 的辅助类函数,完全兼调用 gorm) 173 | 174 | ``` 175 | // FetchByPrimaryKey primary or index 获取唯一内容 176 | func (obj *_UserAccountTblMgr) FetchByPrimaryKey(ID int) (result UserAccountTbl, err error) { 177 | err = obj.DB.Table(obj.GetTableName()).Where("id = ?", ID).Find(&result).Error 178 | if err == nil && obj.isRelated { 179 | { 180 | var info UserInfoTbl // 用户信息 181 | err = obj.DB.Table("user_info_tbl").Where("id = ?", result.UserInfoTblID).Find(&info).Error 182 | if err != nil { 183 | return 184 | } 185 | result.UserInfoTbl = info 186 | } 187 | } 188 | 189 | return 190 | } 191 | 192 | ``` 193 | 194 | ### [更多>>>](https://github.com/xxjwxc/gormt/tree/master/doc/func_cn.md) 195 | 196 | ### [函数调用示例>>>](https://github.com/xxjwxc/gormt/blob/master/data/view/genfunc/genfunc_test.go) 197 | 198 | ## 7. 分页展示 199 | ### [gormt中分页查询的使用](https://xiaojujiang.blog.csdn.net/article/details/122315454?spm=1001.2014.3001.5502) 200 | 201 | ## 8. 构建 202 | ``` 203 | make windows 204 | make linux 205 | make mac 206 | ``` 207 | or 208 | 209 | ``` 210 | go generate 211 | ``` 212 | 213 | 214 | ### 说明:windows 不支持中文默认方式。ASCALL 模式 215 | 切换编码方式 216 | ``` 217 | CHCP 65001 218 | ``` 219 | 220 | ### 列注释 tag 221 | 222 | - 给列添加注释以`[@gorm default:'test']`开头即可 223 | - 比如`[@gorm default:'test';->;<-:create]这是注释内容` 表示默认值为'test',允许读,更新创建 224 | - 外键注释使用`[@fk tableName.columnName]这是注释内容` 表示关联到`tableName`的`columnName`列 225 | 226 | 227 | ## 9. 提供一个windows 可视化工具 228 | 229 | ![图片描述](/image/gormt/1.png) 230 | 231 | ![图片描述](/image/gormt/2.jpg) 232 | 233 | ![图片描述](/image/gormt/3.jpg) 234 | 235 | ![图片描述](/image/gormt/4.jpg) 236 | 237 | [下载地址](https://github.com/xxjwxc/gormt/releases/download/v0.3.8/v1.0.zip) 238 | 239 | 240 | - ###### [传送门](https://xxjwxc.github.io/post/gormtools/) 241 | 242 | ## 点赞时间线 243 | 244 | [![Stargazers over time](https://starchart.cc/xxjwxc/gormt.svg)](https://starchart.cc/xxjwxc/gormt) 245 | -------------------------------------------------------------------------------- /config.yml: -------------------------------------------------------------------------------- 1 | base: 2 | is_dev : false 3 | out_dir : ./model # 输出目录 4 | url_tag : json # web url tag(json,db(https://github.com/google/go-querystring)) 5 | language : # 语言(English,中 文) 6 | db_tag : gorm # 数据库标签名(gorm,db) 7 | simple : true # 简单输出(默认只输出gorm主键和字段标签) 8 | user_gorm_model : false # model是否使用gorm.Model 9 | is_db_tag : true # 是否输出 数据库标签(gorm,db) 10 | is_out_sql : false # 是否输出 sql 原信息 11 | is_out_func : true # 是否输出 快捷函数 12 | is_web_tag : true # 是否打web标记(json标记前提条件) 13 | is_web_tag_pk_hidden: true # web标记是否隐藏主键 14 | is_foreign_key : true # 是否导出外键关联 15 | is_gui : false # 是否ui模式显示 16 | is_table_name : true # 是否直接生成表名 17 | is_column_name : true # 是否直接生成列名 18 | is_null_to_point : false # 数据库默认 'DEFAULT NULL' 时设置结构为指针类型 19 | is_null_to_sql_null: false # 数据库默认 'DEFAULT NULL' 时设置结构为sql.NULL is_null_to_point如果为true,则is_null_to_sql_null不生效 20 | table_prefix : "" # 表前缀, 如果有则使用, 没有留空(如果表前缀以"-"开头,则表示去掉该前缀,struct、文件名都会去掉该前缀) 21 | table_names: "" # 指定表生成,多个表用,隔开 22 | is_out_file_by_table_name: false # 是否根据表名生成多个model 23 | is_out_page: true # 是否输出分页函数 24 | 25 | db_info: 26 | host : 127.0.0.1 # type=1的时候,host为yml文件全路径 27 | port : 3306 28 | username : root 29 | password : 123456 30 | database : matrix 31 | type: 0 # 数据库类型:0:mysql , 1:sqlite , 2:mssql 32 | self_type_define: # 自定义数据类型映射 33 | datetime: time.Time 34 | time: time.Time 35 | ^(int)[(]\d+[)]: int 36 | out_file_name: "" # 自定义生成文件名 37 | web_tag_type: 0 # json tag类型 0: 小驼峰 1: 下划线 38 | 39 | # sqlite 40 | # db_info: 41 | # host : /Users/xxj/Downloads/caoguo # type=1的时候,host为yml文件全路径 42 | # port : 43 | # username : 44 | # password : 45 | # database : 46 | # type: 1 # 数据库类型:0:mysql , 1:sqlite , 2:mssql -------------------------------------------------------------------------------- /data/cmd/cmd.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | 7 | "github.com/xxjwxc/public/mylog" 8 | 9 | "github.com/xxjwxc/gormt/data/view/gtools" 10 | 11 | "github.com/xxjwxc/gormt/data/config" 12 | 13 | "github.com/spf13/cobra" 14 | "github.com/xxjwxc/public/mycobra" 15 | "gopkg.in/go-playground/validator.v9" 16 | ) 17 | 18 | var rootCmd = &cobra.Command{ 19 | Use: "main", 20 | Short: "gorm mysql reflect tools", 21 | Long: `base on gorm tools for mysql database to golang struct`, 22 | Run: func(cmd *cobra.Command, args []string) { 23 | gtools.Execute() 24 | // Start doing things.开始做事情 25 | }, 26 | } 27 | 28 | // Execute adds all child commands to the root command and sets flags appropriately. 29 | // This is called by main.main(). It only needs to happen once to the rootCmd. 30 | func Execute() { 31 | if err := rootCmd.Execute(); err != nil { 32 | os.Exit(1) 33 | } 34 | } 35 | 36 | func init() { 37 | cobra.OnInitialize(initConfig) 38 | 39 | rootCmd.PersistentFlags().StringP("host", "H", "", "数据库地址.(注意-H为大写)") 40 | rootCmd.MarkFlagRequired("host") 41 | rootCmd.PersistentFlags().StringP("user", "u", "", "用户名.") 42 | rootCmd.MarkFlagRequired("user") 43 | 44 | rootCmd.PersistentFlags().StringP("password", "p", "", "密码.") 45 | rootCmd.MarkFlagRequired("password") 46 | 47 | rootCmd.PersistentFlags().StringP("database", "d", "", "数据库名") 48 | rootCmd.MarkFlagRequired("database") 49 | 50 | rootCmd.PersistentFlags().StringP("outdir", "o", "", "输出目录") 51 | rootCmd.MarkFlagRequired("outdir") 52 | 53 | rootCmd.PersistentFlags().BoolP("singular", "s", true, "是否禁用表名复数") 54 | rootCmd.MarkFlagRequired("singular") 55 | 56 | rootCmd.PersistentFlags().BoolP("foreign", "f", false, "是否导出外键关联") 57 | rootCmd.MarkFlagRequired("foreign key") 58 | 59 | rootCmd.PersistentFlags().BoolP("fun", "F", false, "是否导出函数") 60 | rootCmd.MarkFlagRequired("func export") 61 | 62 | rootCmd.PersistentFlags().BoolP("gui", "g", false, "是否ui显示模式") 63 | rootCmd.MarkFlagRequired("show on gui") 64 | 65 | rootCmd.PersistentFlags().StringP("url", "l", "", "url标签(json,url)") 66 | rootCmd.MarkFlagRequired("url tag") 67 | 68 | rootCmd.Flags().Int("port", 3306, "端口号") 69 | 70 | rootCmd.Flags().StringP("table_prefix", "t", "", "表前缀") 71 | //add table name. 增加表名称 72 | rootCmd.Flags().StringP("table_names", "b", "", "表名称") 73 | 74 | } 75 | 76 | // initConfig reads in config file and ENV variables if set. 77 | func initConfig() { 78 | MergeMysqlDbInfo() 79 | validate := validator.New() 80 | err := validate.Struct(config.GetDbInfo()) 81 | if err != nil { 82 | mylog.Info("Can't read cmd: using (-h, --help) to get more info") 83 | mylog.Error(err) 84 | os.Exit(1) 85 | } else { 86 | mylog.Info("using database info:") 87 | mylog.JSON(config.GetDbInfo()) 88 | } 89 | } 90 | 91 | // MergeMysqlDbInfo merge parm 92 | func MergeMysqlDbInfo() { 93 | var tmp = config.GetDbInfo() 94 | mycobra.IfReplace(rootCmd, "database", &tmp.Database) // 如果设置了,更新 95 | mycobra.IfReplace(rootCmd, "host", &tmp.Host) // 如果设置了,更新 96 | mycobra.IfReplace(rootCmd, "password", &tmp.Password) // 如果设置了,更新 97 | mycobra.IfReplace(rootCmd, "port", &tmp.Port) // 如果设置了,更新 98 | mycobra.IfReplace(rootCmd, "user", &tmp.Username) // 如果设置了,更新 99 | config.SetMysqlDbInfo(&tmp) 100 | 101 | url := config.GetURLTag() 102 | mycobra.IfReplace(rootCmd, "url", &url) // 如果设置了,更新 103 | config.SetURLTag(url) 104 | 105 | dir := config.GetOutDir() 106 | mycobra.IfReplace(rootCmd, "outdir", &dir) // 如果设置了,更新 107 | config.SetOutDir(dir) 108 | 109 | fk := config.GetIsForeignKey() 110 | mycobra.IfReplace(rootCmd, "foreign", &fk) // 如果设置了,更新 111 | config.SetForeignKey(fk) 112 | 113 | funcKey := config.GetIsOutFunc() 114 | mycobra.IfReplace(rootCmd, "fun", &funcKey) // 如果设置了,更新 115 | config.SetIsOutFunc(funcKey) 116 | 117 | ig := config.GetIsGUI() 118 | mycobra.IfReplace(rootCmd, "gui", &ig) // 如果设置了,更新 119 | config.SetIsGUI(ig) 120 | 121 | tablePrefix := config.GetTablePrefix() 122 | mycobra.IfReplace(rootCmd, "table_prefix", &tablePrefix) // 如果设置了,更新 123 | config.SetTablePrefix(tablePrefix) 124 | 125 | //update tableNames. 更新tableNames 126 | tableNames := config.GetTableNames() 127 | if tableNames != "" { 128 | tableNames = strings.Replace(tableNames, "'", "", -1) 129 | } 130 | mycobra.IfReplace(rootCmd, "table_names", &tableNames) // 如果设置了,更新 131 | config.SetTableNames(tableNames) 132 | 133 | } 134 | -------------------------------------------------------------------------------- /data/config/MyIni.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/xxjwxc/public/tools" 8 | ) 9 | 10 | // Config custom config struct 11 | type Config struct { 12 | CfgBase `yaml:"base"` 13 | DBInfo DBInfo `yaml:"db_info"` 14 | OutDir string `yaml:"out_dir"` 15 | URLTag string `yaml:"url_tag"` // url tag 16 | Language string `yaml:"language"` // language 17 | DbTag string `yaml:"db_tag"` // 数据库标签(gormt,db) 18 | UserGormModel bool `yaml:"user_gorm_model"` //model是否使用gorm.Model 19 | Simple bool `yaml:"simple"` 20 | IsWEBTag bool `yaml:"is_web_tag"` 21 | IsWebTagPkHidden bool `yaml:"is_web_tag_pk_hidden"` // web标记是否隐藏主键 22 | IsForeignKey bool `yaml:"is_foreign_key"` 23 | IsOutSQL bool `yaml:"is_out_sql"` 24 | IsOutFunc bool `yaml:"is_out_func"` 25 | IsGUI bool `yaml:"is_gui"` // 26 | IsTableName bool `yaml:"is_table_name"` 27 | IsNullToPoint bool `yaml:"is_null_to_point"` // null to porint 28 | IsNullToSqlNull bool `yaml:"is_null_to_sql_null"` 29 | TablePrefix string `yaml:"table_prefix"` // 表前缀 30 | SelfTypeDef map[string]string `yaml:"self_type_define"` 31 | OutFileName string `yaml:"out_file_name"` 32 | WebTagType int `yaml:"web_tag_type"` // 默认小驼峰 33 | TableNames string `yaml:"table_names"` // 表名(多个表名用","隔开) 34 | IsColumnName bool `yaml:"is_column_name"` //是否输出列名 35 | IsOutFileByTableName bool `yaml:"is_out_file_by_table_name"` //是否根据表名生成文件(多个表名生成多个文件) 36 | IsOutPage bool `yaml:"is_out_page"` // 是否输出分页支持 37 | } 38 | 39 | // DBInfo mysql database information. mysql 数据库信息 40 | type DBInfo struct { 41 | Host string `validate:"required"` // Host. 地址 42 | Port int // Port 端口号 43 | Username string // Username 用户名 44 | Password string // Password 密码 45 | Database string // Database 数据库名 46 | Type int // 数据库类型: 0:mysql , 1:sqlite , 2:mssql 47 | } 48 | 49 | // SetMysqlDbInfo Update MySQL configuration information 50 | func SetMysqlDbInfo(info *DBInfo) { 51 | _map.DBInfo = *info 52 | } 53 | 54 | // GetDbInfo Get configuration information .获取数据配置信息 55 | func GetDbInfo() DBInfo { 56 | return _map.DBInfo 57 | } 58 | 59 | // GetMysqlConStr Get MySQL connection string.获取mysql 连接字符串 60 | func GetMysqlConStr() string { 61 | return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local&interpolateParams=True", 62 | _map.DBInfo.Username, 63 | _map.DBInfo.Password, 64 | _map.DBInfo.Host, 65 | _map.DBInfo.Port, 66 | _map.DBInfo.Database, 67 | ) 68 | } 69 | 70 | // SetOutDir Setting Output Directory.设置输出目录 71 | func SetOutDir(outDir string) { 72 | _map.OutDir = outDir 73 | } 74 | 75 | // GetOutDir Get Output Directory.获取输出目录 76 | func GetOutDir() string { 77 | if len(_map.OutDir) == 0 { 78 | _map.OutDir = "./model" 79 | } 80 | 81 | return _map.OutDir 82 | } 83 | 84 | // // SetSingularTable Set Disabled Table Name Plurals.设置禁用表名复数 85 | // func SetSingularTable(b bool) { 86 | // _map.SingularTable = b 87 | // } 88 | 89 | // // GetSingularTable Get Disabled Table Name Plurals.获取禁用表名复数 90 | // func GetSingularTable() bool { 91 | // return _map.SingularTable 92 | // } 93 | 94 | // GetSimple simple output.简单输出 95 | func GetSimple() bool { 96 | return _map.Simple 97 | } 98 | 99 | // SetSimple simple output.简单输出 100 | func SetSimple(b bool) { 101 | _map.Simple = b 102 | } 103 | 104 | // GetIsWEBTag json tag.json标记 105 | func GetIsWEBTag() bool { 106 | return _map.IsWEBTag 107 | } 108 | 109 | // SetIsWEBTag json tag.json标记 110 | func SetIsWEBTag(b bool) { 111 | _map.IsWEBTag = b 112 | } 113 | 114 | // GetIsWebTagPkHidden web tag是否隐藏主键 115 | func GetIsWebTagPkHidden() bool { 116 | return _map.IsWebTagPkHidden 117 | } 118 | 119 | // GetIsForeignKey if is foreign key 120 | func GetIsForeignKey() bool { 121 | return _map.IsForeignKey 122 | } 123 | 124 | // SetForeignKey Set if is foreign key.设置是否外键关联 125 | func SetForeignKey(b bool) { 126 | _map.IsForeignKey = b 127 | } 128 | 129 | // SetIsOutSQL if is output sql . 130 | func SetIsOutSQL(b bool) { 131 | _map.IsOutSQL = b 132 | } 133 | 134 | // GetIsOutSQL if is output sql . 135 | func GetIsOutSQL() bool { 136 | return _map.IsOutSQL 137 | } 138 | 139 | // GetIsOutFunc if is output func . 140 | func GetIsOutFunc() bool { 141 | return _map.IsOutFunc 142 | } 143 | 144 | // SetIsOutFunc if is output func . 145 | func SetIsOutFunc(b bool) { 146 | _map.IsOutFunc = b 147 | } 148 | 149 | // GetIsGUI if is gui show . 150 | func GetIsGUI() bool { 151 | return _map.IsGUI 152 | } 153 | 154 | // SetIsGUI if is gui show . 155 | func SetIsGUI(b bool) { 156 | _map.IsGUI = b 157 | } 158 | 159 | // GetIsTableName if is table name . 160 | func GetIsTableName() bool { 161 | return _map.IsTableName 162 | } 163 | 164 | // SetIsTableName if is table name . 165 | func SetIsTableName(b bool) { 166 | _map.IsTableName = b 167 | } 168 | 169 | // GetURLTag get url tag. 170 | func GetURLTag() string { 171 | if _map.URLTag != "json" && _map.URLTag != "url" { 172 | _map.URLTag = "json" 173 | } 174 | 175 | return _map.URLTag 176 | } 177 | 178 | // SetURLTag set url tag. 179 | func SetURLTag(s string) { 180 | _map.URLTag = s 181 | } 182 | 183 | // GetLG get language tag. 184 | func GetLG() string { 185 | if _map.Language != "English" && _map.Language != "中 文" { 186 | if tools.GetLocalSystemLang(true) == "en" { 187 | _map.Language = "English" 188 | } else { 189 | _map.Language = "中 文" 190 | } 191 | } 192 | 193 | return _map.Language 194 | } 195 | 196 | // SetLG set url tag. 197 | func SetLG(s string) { 198 | _map.Language = s 199 | } 200 | 201 | // GetDBTag get database tag. 202 | func GetDBTag() string { 203 | if _map.DbTag != "gorm" && _map.DbTag != "db" { 204 | _map.DbTag = "gorm" 205 | } 206 | 207 | return _map.DbTag 208 | } 209 | 210 | // SetDBTag get database tag. 211 | func SetDBTag(s string) { 212 | _map.DbTag = s 213 | } 214 | 215 | // GetUserGormModel get `use gorm.Model or not`. 216 | func GetUserGormModel() bool { 217 | return _map.UserGormModel 218 | } 219 | 220 | // SetIsNullToPoint if with null to porint in struct 221 | func SetIsNullToPoint(b bool) { 222 | _map.IsNullToPoint = b 223 | } 224 | 225 | // GetIsNullToPoint get if with null to porint in sturct 226 | func GetIsNullToPoint() bool { 227 | return _map.IsNullToPoint 228 | } 229 | 230 | func SetIsNullToSqlNull(b bool) { 231 | _map.IsNullToSqlNull = b 232 | } 233 | 234 | func GetIsNullToSqlNull() bool { 235 | return _map.IsNullToSqlNull 236 | } 237 | 238 | // SetTablePrefix set table prefix 239 | func SetTablePrefix(t string) { 240 | _map.TablePrefix = t 241 | } 242 | 243 | // GetTablePrefix get table prefix 244 | func GetTablePrefix() string { 245 | return _map.TablePrefix 246 | } 247 | 248 | // SetSelfTypeDefine 设置自定义字段映射 249 | func SetSelfTypeDefine(data map[string]string) { 250 | _map.SelfTypeDef = data 251 | } 252 | 253 | // GetSelfTypeDefine 获取自定义字段映射 254 | func GetSelfTypeDefine() map[string]string { 255 | return _map.SelfTypeDef 256 | } 257 | 258 | // SetOutFileName 设置输出文件名 259 | func SetOutFileName(s string) { 260 | _map.OutFileName = s 261 | } 262 | 263 | // GetOutFileName 获取输出文件名 264 | func GetOutFileName() string { 265 | return _map.OutFileName 266 | } 267 | 268 | // SetWebTagType 设置json tag类型 269 | func SetWebTagType(i int) { 270 | _map.WebTagType = i 271 | } 272 | 273 | // GetWebTagType 获取json tag类型 274 | func GetWebTagType() int { 275 | return _map.WebTagType 276 | } 277 | 278 | //GetTableNames get format tableNames by config. 获取格式化后设置的表名 279 | func GetTableNames() string { 280 | var sb strings.Builder 281 | if _map.TableNames != "" { 282 | tableNames := _map.TableNames 283 | tableNames = strings.TrimLeft(tableNames, ",") 284 | tableNames = strings.TrimRight(tableNames, ",") 285 | if tableNames == "" { 286 | return "" 287 | } 288 | 289 | sarr := strings.Split(_map.TableNames, ",") 290 | if len(sarr) == 0 { 291 | fmt.Printf("tableNames is vailed, genmodel will by default global") 292 | return "" 293 | } 294 | 295 | for i, val := range sarr { 296 | sb.WriteString(fmt.Sprintf("'%s'", val)) 297 | if i != len(sarr)-1 { 298 | sb.WriteString(",") 299 | } 300 | } 301 | } 302 | return sb.String() 303 | } 304 | 305 | //GetOriginTableNames get origin tableNames. 获取原始的设置的表名 306 | func GetOriginTableNames() string { 307 | return _map.TableNames 308 | } 309 | 310 | //SetTableNames set tableNames. 设置生成的表名 311 | func SetTableNames(tableNames string) { 312 | _map.TableNames = tableNames 313 | } 314 | 315 | //GetIsColumnName get gen columnName config . 获取生成列名的config 316 | func GetIsColumnName() bool { 317 | return _map.IsColumnName 318 | } 319 | 320 | //SetIsColumnName set gen ColumnName config. 设置生成列名的config 321 | func SetIsColumnName(isColumnName bool) { 322 | _map.IsColumnName = isColumnName 323 | } 324 | 325 | //GetIsOutFileByTableName get gen columnName config . 设置是否根据表名生成文件 326 | func GetIsOutFileByTableName() bool { 327 | return _map.IsOutFileByTableName 328 | } 329 | 330 | // GetIsOutPage 是否输出分页函数支持 331 | func GetIsOutPage() bool { 332 | return _map.IsOutPage 333 | } 334 | -------------------------------------------------------------------------------- /data/config/common.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "path" 7 | 8 | "github.com/xxjwxc/public/mylog" 9 | 10 | "github.com/xxjwxc/public/dev" 11 | "github.com/xxjwxc/public/tools" 12 | "gopkg.in/yaml.v3" 13 | ) 14 | 15 | // CfgBase base config struct 16 | type CfgBase struct { 17 | // SerialNumber string `json:"serial_number" yaml:"serial_number"` // version.版本号 18 | // ServiceName string `json:"service_name" yaml:"service_name"` // service name .service名字 19 | // ServiceDisplayName string json:"service_display_name" yaml:"service_display_name" // display name .显示名 20 | // ServiceDesc json:"service_desc" yaml:"service_desc" // sercice desc .service描述 21 | IsDev bool `json:"is_dev" yaml:"is_dev"` // Is it a development version?是否是开发版本 22 | } 23 | 24 | var _map = Config{ 25 | CfgBase: CfgBase{ 26 | IsDev: false, 27 | }, 28 | DBInfo: DBInfo{ 29 | Host: "127.0.0.1", 30 | Port: 3306, 31 | Username: "root", 32 | Password: "root", 33 | Database: "test", 34 | }, 35 | OutDir: "./model", 36 | URLTag: "json", 37 | Language: "中 文", 38 | DbTag: "gorm", 39 | UserGormModel: false, 40 | Simple: false, 41 | IsWEBTag: false, 42 | // SingularTable: true, 43 | IsForeignKey: true, 44 | IsOutSQL: false, 45 | IsOutFunc: true, 46 | IsGUI: false, 47 | TablePrefix: "", 48 | SelfTypeDef: make(map[string]string), 49 | WebTagType: 0, 50 | TableNames: "", 51 | IsColumnName: true, 52 | IsOutFileByTableName: false, 53 | } 54 | 55 | var configPath string 56 | 57 | func init() { 58 | configPath = path.Join(tools.GetCurrentDirectory(), "config.yml") // 先找本程序文件夹 59 | if !tools.CheckFileIsExist(configPath) { // dont find it 60 | configPath = path.Join(tools.GetModelPath(), "config.yml") 61 | if !tools.CheckFileIsExist(configPath) { 62 | mylog.ErrorString("config.yml not exit. using default config") 63 | } 64 | } 65 | 66 | err := onInit() 67 | if err != nil { 68 | fmt.Println("Load config file error: ", err.Error()) 69 | panic(err) 70 | } 71 | dev.OnSetDev(_map.IsDev) 72 | } 73 | 74 | func onInit() error { 75 | err := InitFile(configPath) 76 | if err != nil { 77 | fmt.Println("Load config file error: ", err.Error()) 78 | return err 79 | } 80 | return nil 81 | } 82 | 83 | // InitFile default value from file . 84 | func InitFile(filename string) error { 85 | // if _, e := os.Stat(filename); e != nil { 86 | // fmt.Println("init default config file: ", filename) 87 | // if err := SaveToFile(); err == nil { 88 | // InitFile(filename) 89 | // return nil 90 | // } else { 91 | // fmt.Println("shit,fail", err) 92 | // } 93 | // // os.Exit(0) 94 | // } 95 | bs, err := ioutil.ReadFile(filename) 96 | if err != nil { 97 | return err 98 | } 99 | if err := yaml.Unmarshal(bs, &_map); err != nil { 100 | fmt.Println("read config file error: ", err.Error()) 101 | return err 102 | } 103 | return nil 104 | } 105 | 106 | // GetServiceConfig Get service configuration information 107 | // func GetServiceConfig() (name, displayName, desc string) { 108 | // name = _map.ServiceName 109 | // displayName = _map.ServiceDisplayName 110 | // desc = _map.SerciceDesc 111 | // return 112 | // } 113 | 114 | // GetIsDev is is dev 115 | func GetIsDev() bool { 116 | return _map.IsDev 117 | } 118 | 119 | // SetIsDev is is dev 120 | func SetIsDev(b bool) { 121 | _map.IsDev = b 122 | } 123 | 124 | // SaveToFile save config info to file 125 | func SaveToFile() error { 126 | d, err := yaml.Marshal(_map) 127 | if err != nil { 128 | return err 129 | } 130 | tools.WriteFile(configPath, []string{ 131 | string(d), 132 | }, true) 133 | return nil 134 | } 135 | -------------------------------------------------------------------------------- /data/config/test_def.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | ) 7 | 8 | const ( 9 | testFile = ` 10 | serial_number : "1.0" #版本号 11 | service_name : #服务名 12 | service_displayname : #服务显示名 13 | sercice_desc : #服务描述 14 | is_dev : false # 是否开发者模式 15 | out_dir : ./db # 输出目录 16 | simple : true #简单输出 17 | isJsonTag : true #是否打json标记 18 | mysql_info: 19 | host : 127.0.0.1 20 | port : 3306 21 | username : root 22 | password : qwer 23 | database : oauth_db 24 | ` 25 | ) 26 | 27 | // IsRunTesting Determine whether to use it in a test environment.判断是否在测试环境下使用 28 | func IsRunTesting() bool { 29 | if len(os.Args) > 1 { 30 | return strings.HasPrefix(os.Args[1], "-test") 31 | } 32 | return false 33 | } 34 | -------------------------------------------------------------------------------- /data/dlg/cmd_darwin.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import "os/exec" 4 | 5 | func openURL(url string) { 6 | exec.Command(`open`, url).Start() 7 | } 8 | -------------------------------------------------------------------------------- /data/dlg/cmd_linux.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import "os/exec" 4 | 5 | func openURL(url string) { 6 | exec.Command(`xdg-open`, url).Start() 7 | } 8 | -------------------------------------------------------------------------------- /data/dlg/cmd_windows.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import "os/exec" 4 | 5 | func openURL(url string) { 6 | exec.Command(`cmd`, `/c`, `start`, url).Start() // 有GUI调用 7 | } 8 | -------------------------------------------------------------------------------- /data/dlg/common.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | 7 | "github.com/jroimartin/gocui" 8 | "github.com/xxjwxc/gormt/data/view/model" 9 | "github.com/xxjwxc/gormt/data/view/model/genmysql" 10 | "github.com/xxjwxc/gormt/data/view/model/gensqlite" 11 | 12 | "github.com/xxjwxc/gormt/data/config" 13 | 14 | "github.com/xxjwxc/public/mylog" 15 | "github.com/xxjwxc/public/tools" 16 | ) 17 | 18 | func division(a int, b float32) int { 19 | r := float32(a) / b 20 | return (int)(r) 21 | } 22 | 23 | func (dlg *menuDetails) nextButton(g *gocui.Gui, v *gocui.View) error { 24 | dlg.btnList[dlg.active].UnFocus() 25 | dlg.active = (dlg.active + 1) % len(dlg.btnList) 26 | menuFocusButton(g) 27 | return nil 28 | } 29 | func menuFocusButton(g *gocui.Gui) { 30 | setlog(g, SLocalize(btnLogArr[menuDlg.active])) 31 | menuDlg.btnList[menuDlg.active].Focus() 32 | } 33 | 34 | func (dlg *menuDetails) prevButton(g *gocui.Gui, v *gocui.View) error { 35 | dlg.btnList[dlg.active].UnFocus() 36 | if dlg.active == 0 { 37 | dlg.active = len(dlg.btnList) 38 | } 39 | dlg.active-- 40 | menuFocusButton(g) 41 | return nil 42 | } 43 | 44 | func (dlg *menuDetails) Draw() { 45 | for _, b := range dlg.btnList { 46 | b.Draw() 47 | } 48 | } 49 | 50 | // OnDestroy destroy windows 51 | func OnDestroy(g *gocui.Gui, v *gocui.View) error { 52 | return gocui.ErrQuit 53 | } 54 | 55 | func setCurrentViewOnTop(g *gocui.Gui, name string) (*gocui.View, error) { 56 | if _, err := g.SetCurrentView(name); err != nil { 57 | return nil, err 58 | } 59 | return g.SetViewOnTop(name) 60 | } 61 | 62 | func requireValidator(value string) bool { 63 | if value == "" { 64 | return false 65 | } 66 | return true 67 | } 68 | 69 | func getBool(bstr string) bool { 70 | if bstr == "true" || bstr == " 是" { 71 | return true 72 | } 73 | 74 | return false 75 | } 76 | 77 | func generate(g *gocui.Gui, v *gocui.View) { 78 | var modeldb model.IModel 79 | switch config.GetDbInfo().Type { 80 | case 0: 81 | modeldb = genmysql.GetModel() 82 | case 1: 83 | modeldb = gensqlite.GetModel() 84 | } 85 | if modeldb == nil { 86 | mylog.Error(fmt.Errorf("modeldb not fund : please check db_info.type (0:mysql , 1:sqlite , 2:mssql) ")) 87 | return 88 | } 89 | 90 | pkg := modeldb.GenModel() 91 | // just for test 92 | // out, _ := json.Marshal(pkg) 93 | // tools.WriteFile("test.txt", []string{string(out)}, true) 94 | 95 | list, mo := model.Generate(pkg) 96 | 97 | addlog(g, "\n \033[32;7m 开 始 : begin \033[0m\n") 98 | 99 | for _, v := range list { 100 | path := config.GetOutDir() + "/" + v.FileName 101 | tools.WriteFile(path, []string{v.FileCtx}, true) 102 | 103 | addlog(g, " formatting differs from goimport's:") 104 | cmd, _ := exec.Command("goimports", "-l", "-w", path).Output() 105 | addlog(g, " "+string(cmd)) 106 | } 107 | 108 | addlog(g, "\033[32;7m 所 有 已 完 成 : ALL completed!! \033[0m\n") 109 | // build item 110 | gPkg = mo.GetPackage() 111 | buildList(g, v) 112 | } 113 | -------------------------------------------------------------------------------- /data/dlg/cui.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "strconv" 7 | "strings" 8 | 9 | "github.com/xxjwxc/public/tools" 10 | 11 | "github.com/xxjwxc/gormt/data/config" 12 | 13 | "github.com/jroimartin/gocui" 14 | "github.com/xxjwxc/public/myclipboard" 15 | "github.com/xxjwxc/public/mycui" 16 | ) 17 | 18 | func nextView(g *gocui.Gui, v *gocui.View) error { 19 | nextIndex := (mainIndex + 1) % len(mainViewArr) 20 | name := mainViewArr[nextIndex] 21 | 22 | if _, err := g.SetCurrentView(name); err != nil { // 设置选中 23 | return err 24 | } 25 | g.SelFgColor = gocui.ColorGreen // 设置边框颜色 26 | g.FgColor = gocui.ColorWhite 27 | 28 | switch name { 29 | case _menuDefine: 30 | //g.Cursor = false // 光标 31 | // g.FgColor = gocui.ColorGreen 32 | menuDlg.btnList[menuDlg.active].Focus() 33 | case _listDefine: 34 | //g.Cursor = false 35 | menuDlg.btnList[menuDlg.active].UnFocus() 36 | case _viewDefine: 37 | //g.Cursor = true 38 | menuDlg.btnList[menuDlg.active].UnFocus() 39 | } 40 | 41 | mainIndex = nextIndex 42 | return nil 43 | } 44 | 45 | func mainLayout(g *gocui.Gui) error { 46 | maxX, maxY := g.Size() 47 | if v, err := g.SetView("main_title", maxX/2-16, -1, maxX/2+16, 1); err != nil { 48 | if err != gocui.ErrUnknownView { 49 | return err 50 | } 51 | v.Highlight = true 52 | v.SelFgColor = gocui.ColorGreen | gocui.AttrUnderline 53 | fmt.Fprintln(v, "https://github.com/xxjwxc/gormt") 54 | } 55 | 56 | if v, err := g.SetView(_menuDefine, 0, 1, division(maxX, uiPart[0])-1, division(maxY, uiPart[1])-1); err != nil { 57 | if err != gocui.ErrUnknownView { 58 | return err 59 | } 60 | v.Title = SLocalize(_menuDefine) 61 | // v.Editable = true // 是否可以编辑 62 | v.Wrap = true 63 | v.Autoscroll = true 64 | // g.FgColor = gocui.ColorGreen 65 | } 66 | 67 | if v, err := g.SetView(_listDefine, 0, division(maxY, uiPart[1]), division(maxX, uiPart[0])-1, maxY-1); err != nil { 68 | if err != gocui.ErrUnknownView { 69 | return err 70 | } 71 | v.Title = SLocalize(_listDefine) 72 | // v.Wrap = true 73 | // v.Autoscroll = true 74 | v.Highlight = true 75 | v.SelBgColor = gocui.ColorGreen 76 | v.SelFgColor = gocui.ColorBlack 77 | // if _, err := g.SetCurrentView(_menuDefine); err != nil { 78 | // return err 79 | // } 80 | } 81 | 82 | if v, err := g.SetView(_viewDefine, division(maxX, uiPart[0]), 1, maxX-1, maxY-3); err != nil { 83 | if err != gocui.ErrUnknownView { 84 | return err 85 | } 86 | v.Title = SLocalize(_viewDefine) 87 | v.Wrap = true 88 | v.Autoscroll = true 89 | v.Editable = true 90 | } 91 | 92 | nemuLayOut(g) // menuLayOut 93 | return nil 94 | } 95 | 96 | func nemuLayOut(g *gocui.Gui) { 97 | menuDlg = &menuDetails{} 98 | menuDlg.btnList = append(menuDlg.btnList, 99 | mycui.NewButton(g, _run, SLocalize(_run), 0, 2, 3).SetTextColor(gocui.ColorRed|gocui.AttrReverse, gocui.ColorWhite). 100 | AddHandler(gocui.KeyArrowUp, menuDlg.prevButton).AddHandler(gocui.KeyArrowDown, menuDlg.nextButton). 101 | AddHandler(gocui.KeyEnter, enterRun).AddHandler(gocui.MouseLeft, enterRun)) 102 | 103 | menuDlg.btnList = append(menuDlg.btnList, 104 | mycui.NewButton(g, _set, SLocalize(_set), 0, 4, 3). 105 | AddHandler(gocui.KeyArrowUp, menuDlg.prevButton).AddHandler(gocui.KeyArrowDown, menuDlg.nextButton). 106 | AddHandler(gocui.KeyEnter, enterSet).AddHandler(gocui.MouseLeft, enterSet)) 107 | 108 | maxX, maxY := g.Size() // division(maxY, uiPart[1]) 109 | clipboardBtn = mycui.NewButton(g, _clipboardBtn, SLocalize(_clipboardBtn), division(maxX, uiPart[0])+2, maxY-3, 5). 110 | AddHandler(gocui.KeyEnter, enterClipboard).AddHandler(gocui.MouseLeft, enterClipboard) 111 | clipboardBtn.Draw() 112 | 113 | menuDlg.Draw() 114 | menuFocusButton(g) 115 | } 116 | 117 | func keybindings(g *gocui.Gui) { 118 | if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, OnDestroy); err != nil { // 退出事件 119 | log.Panicln(err) 120 | } 121 | if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, nextView); err != nil { // tab next事件 122 | log.Panicln(err) 123 | } 124 | if err := g.SetKeybinding("", gocui.KeyEsc, gocui.ModNone, buttonCancel); err != nil { 125 | log.Panicln(err) 126 | } 127 | if err := g.SetKeybinding("", gocui.KeyCtrlQ, gocui.ModNone, buttonCancel); err != nil { 128 | log.Panicln(err) 129 | } 130 | if err := g.SetKeybinding("main_title", gocui.MouseLeft, gocui.ModNone, about); err != nil { 131 | log.Panicln(err) 132 | } 133 | if err := g.SetKeybinding(_listDefine, gocui.KeyArrowDown, gocui.ModNone, listDown); err != nil { 134 | log.Panicln(err) 135 | } 136 | if err := g.SetKeybinding(_listDefine, gocui.KeyArrowUp, gocui.ModNone, listUp); err != nil { 137 | log.Panicln(err) 138 | } 139 | if err := g.SetKeybinding(_listDefine, gocui.KeyEnter, gocui.ModNone, showStruct); err != nil { 140 | log.Panicln(err) 141 | } 142 | if err := g.SetKeybinding(_listDefine, gocui.MouseLeft, gocui.ModNone, showStruct); err != nil { 143 | log.Panicln(err) 144 | } 145 | 146 | } 147 | 148 | ///////////////////signal slot /////////// 149 | func about(g *gocui.Gui, v *gocui.View) error { 150 | openURL("https://github.com/xxjwxc/gormt") 151 | return nil 152 | } 153 | 154 | func setlog(g *gocui.Gui, str string) error { 155 | logView, err := g.View(_viewDefine) 156 | if err == nil { 157 | logView.Clear() 158 | fmt.Fprintln(logView, str) 159 | } 160 | 161 | return err 162 | } 163 | 164 | func addlog(g *gocui.Gui, str string) error { 165 | logView, err := g.View(_viewDefine) 166 | if err == nil { 167 | fmt.Fprintln(logView, str) 168 | } 169 | 170 | return err 171 | } 172 | 173 | func enterClipboard(g *gocui.Gui, v *gocui.View) error { 174 | myclipboard.Set(copyInfo) 175 | 176 | maxX, _ := g.Size() 177 | modal := mycui.NewModal(g, division(maxX, uiPart[0])+5, 10, division(maxX, uiPart[0])+35). 178 | SetTextColor(gocui.ColorRed).SetText("copy success \n 已 复 制 到 剪 切 板 ") 179 | modal.Mouse = true 180 | // modal.SetBgColor(gocui.ColorRed) 181 | _handle := func(g *gocui.Gui, v *gocui.View) error { 182 | modal.Close() 183 | return nil 184 | } 185 | modal.AddButton("ok", "OK", gocui.KeyEnter, _handle).AddHandler(gocui.MouseLeft, _handle) 186 | modal.Draw() 187 | 188 | return nil 189 | } 190 | 191 | func enterRun(g *gocui.Gui, v *gocui.View) error { 192 | setlog(g, "run .... ing") 193 | generate(g, v) 194 | return nil 195 | } 196 | 197 | func enterSet(g *gocui.Gui, v *gocui.View) error { 198 | maxX, _ := g.Size() 199 | setlog(g, "") 200 | // new form 201 | form = mycui.NewForm(g, "set_ui", "Sign Up", division(maxX, uiPart[0])+2, 2, 0, 0) 202 | 203 | // add input field 204 | form.AddInputField("out_dir", SLocalize("out_dir"), formPart[0], formPart[1]).SetText(config.GetOutDir()). 205 | AddValidate("required input", requireValidator) 206 | form.AddInputField("db_host", SLocalize("db_host"), formPart[0], formPart[1]).SetText(config.GetDbInfo().Host). 207 | AddValidate("required input", requireValidator) 208 | form.AddInputField("db_port", SLocalize("db_port"), formPart[0], formPart[1]).SetText(tools.AsString(config.GetDbInfo().Port)). 209 | AddValidate("required input", requireValidator) 210 | form.AddInputField("db_usename", SLocalize("db_usename"), formPart[0], formPart[1]).SetText(config.GetDbInfo().Username). 211 | AddValidate("required input", requireValidator) 212 | form.AddInputField("db_pwd", SLocalize("db_pwd"), formPart[0], formPart[1]).SetText(config.GetDbInfo().Password). 213 | SetMask().SetMaskKeybinding(gocui.KeyCtrlA). 214 | AddValidate("required input", requireValidator) 215 | form.AddInputField("db_name", SLocalize("db_name"), formPart[0], formPart[1]).SetText(config.GetDbInfo().Database). 216 | AddValidate("required input", requireValidator) 217 | form.AddSelect("db_type", SLocalize("db_type"), formPart[0], formPart[2]).AddOptions(getDBTypeList()...). 218 | SetSelected(GetDBTypeStr(config.GetDbInfo().Type)) 219 | // add select 220 | form.AddSelect("is_dev", SLocalize("is_dev"), formPart[0], formPart[2]). 221 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetIsDev()))) 222 | form.AddSelect("is_simple", SLocalize("is_simple"), formPart[0], formPart[2]). 223 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetSimple()))) 224 | form.AddSelect("is_out_sql", SLocalize("is_out_sql"), formPart[0], formPart[2]). 225 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetIsOutSQL()))) 226 | form.AddSelect("is_out_func", SLocalize("is_out_func"), formPart[0], formPart[2]). 227 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetIsOutFunc()))) 228 | form.AddSelect("is_foreign_key", SLocalize("is_foreign_key"), formPart[0], formPart[2]). 229 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetIsForeignKey()))) 230 | form.AddSelect("is_gui", SLocalize("is_gui"), formPart[0], formPart[2]). 231 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetIsGUI()))) 232 | form.AddSelect("is_table_name", SLocalize("is_table_name"), formPart[0], formPart[2]). 233 | AddOptions(SLocalize("true"), SLocalize("false")).SetSelected(SLocalize(tools.AsString(config.GetIsTableName()))) 234 | form.AddSelect("url_tag", SLocalize("url_tag"), formPart[0], formPart[2]). 235 | AddOptions("json", "url").SetSelected(tools.AsString(config.GetURLTag())) 236 | form.AddSelect("db_tag", SLocalize("db_tag"), formPart[0], formPart[2]). 237 | AddOptions("gorm", "db").SetSelected(config.GetDBTag()) 238 | form.AddSelect("language", SLocalize("language"), formPart[0], formPart[2]). 239 | AddOptions("English", "中 文").SetSelected(config.GetLG()) 240 | 241 | // add button 242 | form.AddButton("save", SLocalize("save"), buttonSave).AddHandler(gocui.MouseLeft, buttonSave) 243 | form.AddButton("cancel", SLocalize("cancel"), buttonCancel).AddHandler(gocui.MouseLeft, buttonCancel) 244 | form.AddButton("about", SLocalize("about"), about).AddHandler(gocui.MouseLeft, about) 245 | 246 | form.Draw() 247 | 248 | return nil 249 | } 250 | 251 | func buttonCancel(g *gocui.Gui, v *gocui.View) error { 252 | menuFocusButton(g) 253 | if form != nil { 254 | err := form.Close(g, nil) 255 | form = nil 256 | return err 257 | } 258 | return nil 259 | } 260 | 261 | func buttonSave(g *gocui.Gui, v *gocui.View) error { 262 | maxX, _ := g.Size() 263 | mp := form.GetFieldTexts() 264 | config.SetOutDir(mp["out_dir"]) 265 | 266 | var dbInfo config.DBInfo 267 | dbInfo.Host = mp["db_host"] 268 | port, err := strconv.Atoi(mp["db_port"]) 269 | if err != nil { 270 | modal := mycui.NewModal(g, division(maxX, uiPart[0])+5, 10, division(maxX, uiPart[0])+35).SetTextColor(gocui.ColorRed).SetText("port error") 271 | 272 | _handle := func(g *gocui.Gui, v *gocui.View) error { 273 | modal.Close() 274 | form.SetCurrentItem(form.GetCurrentItem()) 275 | return nil 276 | } 277 | // modal.SetBgColor(gocui.ColorRed) 278 | modal.AddButton("ok", "OK", gocui.KeyEnter, _handle).AddHandler(gocui.MouseLeft, _handle) 279 | 280 | modal.Draw() 281 | return nil 282 | } 283 | 284 | dbInfo.Port = port 285 | dbInfo.Username = mp["db_usename"] 286 | dbInfo.Password = mp["db_pwd"] 287 | dbInfo.Database = mp["db_name"] 288 | mp = form.GetSelectedOpts() 289 | 290 | dbInfo.Type = GetDBTypeID(mp["db_type"]) 291 | config.SetMysqlDbInfo(&dbInfo) 292 | 293 | config.SetIsDev(getBool(mp["is_dev"])) 294 | config.SetSimple(getBool(mp["is_simple"])) 295 | config.SetIsOutSQL(getBool(mp["is_out_sql"])) 296 | config.SetIsOutFunc(getBool(mp["is_out_func"])) 297 | config.SetForeignKey(getBool(mp["is_foreign_key"])) 298 | config.SetIsGUI(getBool(mp["is_gui"])) 299 | config.SetIsTableName(getBool(mp["is_table_name"])) 300 | config.SetIsColumnName(getBool(mp["is_column_name"])) 301 | config.SetURLTag(mp["url_tag"]) 302 | config.SetDBTag(mp["db_tag"]) 303 | config.SetLG(mp["language"]) 304 | 305 | config.SaveToFile() 306 | modal := mycui.NewModal(g, division(maxX, uiPart[0])+5, 10, division(maxX, uiPart[0])+35).SetText("save success") 307 | _handle := func(g *gocui.Gui, v *gocui.View) error { 308 | modal.Close() 309 | buttonCancel(g, v) 310 | return nil 311 | } 312 | modal.AddButton("ok", "OK", gocui.KeyEnter, _handle).AddHandler(gocui.MouseLeft, _handle) 313 | modal.Draw() 314 | 315 | return nil 316 | } 317 | 318 | func buildList(g *gocui.Gui, v *gocui.View) error { 319 | listView, err := g.View(_listDefine) 320 | if err != nil { 321 | panic(err) 322 | } 323 | 324 | listView.Clear() 325 | for _, info := range gPkg.Structs { 326 | fmt.Fprintln(listView, info.Name) 327 | } 328 | 329 | return nil 330 | } 331 | 332 | func showStruct(g *gocui.Gui, v *gocui.View) error { 333 | var l string 334 | var err error 335 | 336 | _, cy := v.Cursor() 337 | if l, err = v.Line(cy); err != nil { 338 | l = "" 339 | } 340 | 341 | var out, out1 []string 342 | for _, v := range gPkg.Structs { 343 | if v.Name == l { 344 | out = v.GeneratesColor() 345 | out1 = v.Generates() 346 | break 347 | } 348 | } 349 | 350 | setlog(g, "\n\n\n") 351 | for _, v := range out { 352 | addlog(g, v) 353 | } 354 | 355 | copyInfo = strings.Join(out1, "\n") 356 | 357 | return nil 358 | } 359 | 360 | func listDown(g *gocui.Gui, v *gocui.View) error { 361 | if v != nil { 362 | cx, cy := v.Cursor() 363 | if cy < len(gPkg.Structs)-1 { 364 | if err := v.SetCursor(cx, cy+1); err != nil { 365 | ox, oy := v.Origin() 366 | if err := v.SetOrigin(ox, oy+1); err != nil { 367 | return err 368 | } 369 | } 370 | } 371 | } 372 | return nil 373 | } 374 | 375 | func listUp(g *gocui.Gui, v *gocui.View) error { 376 | if v != nil { 377 | ox, oy := v.Origin() 378 | cx, cy := v.Cursor() 379 | if err := v.SetCursor(cx, cy-1); err != nil && oy > 0 { 380 | if err := v.SetOrigin(ox, oy-1); err != nil { 381 | return err 382 | } 383 | } 384 | } 385 | return nil 386 | } 387 | 388 | /////////////////////////////////////////// 389 | 390 | // OnInitDialog init main loop 391 | func OnInitDialog() { 392 | g, err := gocui.NewGui(gocui.OutputNormal) 393 | g.ASCII = true 394 | 395 | if err != nil { 396 | log.Panicln(err) 397 | } 398 | defer g.Close() 399 | 400 | g.Cursor = false // 光标 401 | g.Mouse = true 402 | g.Highlight = true 403 | g.SelFgColor = gocui.ColorGreen // 设置边框颜色 404 | 405 | mainLayout(g) 406 | //g.SetManagerFunc(mainLayout) // 主布局 407 | keybindings(g) 408 | 409 | if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { // 主循环 410 | log.Panicln(err) 411 | } 412 | } 413 | 414 | // GetDBTypeStr 0:mysql , 1:sqlite , 2:mssql 415 | func GetDBTypeStr(tp int) string { 416 | switch tp { 417 | case 0: 418 | return "mysql" 419 | case 1: 420 | return "sqlite" 421 | case 2: 422 | return "mssql" 423 | } 424 | // default 425 | return "mysql" 426 | } 427 | 428 | // GetDBTypeID 0:mysql , 1:sqlite , 2:mssql 429 | func GetDBTypeID(name string) int { 430 | switch name { 431 | case "mysql": 432 | return 0 433 | case "sqlite": 434 | return 1 435 | case "mssql": 436 | return 2 437 | } 438 | // default 439 | return 0 440 | } 441 | 442 | func getDBTypeList() []string { 443 | return []string{"mysql", "sqlite", "mssql"} 444 | } 445 | -------------------------------------------------------------------------------- /data/dlg/def.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import ( 4 | "github.com/xxjwxc/gormt/data/view/genstruct" 5 | "github.com/xxjwxc/public/mycui" 6 | ) 7 | 8 | const ( 9 | _menuDefine = "menu" 10 | _listDefine = "list" 11 | _viewDefine = "view" 12 | _run = "run" 13 | _set = "set" 14 | _clipboardBtn = "clipboardBtn" 15 | ) 16 | 17 | var ( 18 | uiPart = []float32{4, 5} // x,y 对应列表 19 | mainViewArr = []string{_menuDefine, _listDefine, _viewDefine} // 主菜单列表 20 | mainIndex = 0 21 | 22 | btnLogArr = []string{"log_run", "log_set"} // 主菜单列表 23 | formPart = []int{14, 28, 10} 24 | ) 25 | 26 | // menu 内容 27 | type menuDetails struct { 28 | active int 29 | btnList []*mycui.Button 30 | } 31 | 32 | type listDetails struct { 33 | active int 34 | btnList []*mycui.Button 35 | } 36 | 37 | var clipboardBtn *mycui.Button 38 | var copyInfo string 39 | 40 | var menuDlg *menuDetails 41 | var form *mycui.Form 42 | var gPkg genstruct.GenPackage 43 | -------------------------------------------------------------------------------- /data/dlg/i18n.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import ( 4 | "github.com/nicksnyder/go-i18n/v2/i18n" 5 | "github.com/xxjwxc/gormt/data/config" 6 | "github.com/xxjwxc/public/myi18n" 7 | "golang.org/x/text/language" 8 | ) 9 | 10 | /* 11 | Internationalization 国际化 12 | */ 13 | 14 | func init() { 15 | addChinese() 16 | addEnglish() 17 | myi18n.SetLocalLG(getLG()) // default 18 | } 19 | 20 | func getLG() string { 21 | tag := config.GetLG() 22 | if tag == "English" { 23 | return "en" 24 | } 25 | 26 | return "zh" 27 | } 28 | 29 | // SLocalize 获取值 30 | func SLocalize(ID string) string { 31 | return myi18n.Get(ID) 32 | } 33 | 34 | func addChinese() error { 35 | return myi18n.AddMessages(language.Chinese, &i18n.Message{ 36 | ID: "menu", 37 | Other: "菜单", 38 | }, &i18n.Message{ 39 | ID: "list", 40 | Other: "列表", 41 | }, &i18n.Message{ 42 | ID: "view", 43 | Other: "视图", 44 | }, &i18n.Message{ 45 | ID: "run", 46 | Other: "执 行 ⏯ ", 47 | }, &i18n.Message{ 48 | ID: "set", 49 | Other: "设 置 🛠 ", 50 | }, &i18n.Message{ 51 | ID: "clipboardBtn", 52 | Other: "复 制 到 剪 切 板 ", 53 | }, &i18n.Message{ 54 | ID: "out_dir", 55 | Other: " 输 出 目 录 :", 56 | }, &i18n.Message{ 57 | ID: "db_type", 58 | Other: " 数 据 库 类 型 :", 59 | }, &i18n.Message{ 60 | ID: "db_host", 61 | Other: " 数 据 库 地 址 :", 62 | }, &i18n.Message{ 63 | ID: "db_port", 64 | Other: " 数 据 库 端 口 :", 65 | }, &i18n.Message{ 66 | ID: "db_usename", 67 | Other: " 数 据 库 用 户 名 :", 68 | }, &i18n.Message{ 69 | ID: "db_pwd", 70 | Other: " 数 据 库 密 码:", 71 | }, &i18n.Message{ 72 | ID: "db_name", 73 | Other: " 数 据 库 名 字 :", 74 | }, &i18n.Message{ 75 | ID: "is_dev", 76 | Other: " 开 发 模 式:", 77 | }, &i18n.Message{ 78 | ID: "is_simple", 79 | Other: " 简 单 输 出 :", 80 | }, &i18n.Message{ 81 | ID: "is_out_sql", 82 | Other: " 输 出 sql 原 :", 83 | }, &i18n.Message{ 84 | ID: "is_out_func", 85 | Other: " 输 出 快 捷 函 数 :", 86 | }, &i18n.Message{ 87 | ID: "is_foreign_key", 88 | Other: " 导 出 外 键 :", 89 | }, &i18n.Message{ 90 | ID: "is_gui", 91 | Other: " 界 面 模 式 :", 92 | }, &i18n.Message{ 93 | ID: "is_table_name", 94 | Other: " 生 成 表 名 :", 95 | }, &i18n.Message{ 96 | ID: "url_tag", 97 | Other: " web 标 签:", 98 | }, &i18n.Message{ 99 | ID: "db_tag", 100 | Other: " 数 据 库 标 签 :", 101 | }, &i18n.Message{ 102 | ID: "language", 103 | Other: " 语 言 :", 104 | }, &i18n.Message{ 105 | ID: "true", 106 | Other: " 是", 107 | }, &i18n.Message{ 108 | ID: "false", 109 | Other: " 否", 110 | }, &i18n.Message{ 111 | ID: "save", 112 | Other: " 保 存 ", 113 | }, &i18n.Message{ 114 | ID: "cancel", 115 | Other: " 取 消 ", 116 | }, &i18n.Message{ 117 | ID: "about", 118 | Other: " 关 于 作 者", 119 | }, &i18n.Message{ 120 | ID: "log_run", 121 | Other: " Enter : 执 行 \n ↑ ↓: 本 视 图 选 择 \n Tab : 多 视 图 切 换 \n Ctrl+C : 退 出 应 用 \n Ctrl+Q : 退 出 对 话 框 \n 支 持 鼠 标 操 作 方 式 \n \n \033[33;7m 输 入 Enter 直 接 执 行 \033[0m\n ", 122 | }, &i18n.Message{ 123 | ID: "log_set", 124 | Other: " Enter : 执 行 \n ↑ ↓: 本 视 图 选 择 \n Tab : 多 视 图 切 换\n Ctrl+C : 退 出 应 用 \n Ctrl+Q : 退 出 对 话 框 \n 支 持 鼠 标 操 作 方 式 \n \n \033[33;7m 输 入 Enter 打 开 设 置 窗 口 \033[0m\n ", 125 | }) 126 | } 127 | 128 | func addEnglish() error { 129 | return myi18n.AddMessages(language.English, &i18n.Message{ 130 | ID: "menu", 131 | Other: "Menu", 132 | }, &i18n.Message{ 133 | ID: "list", 134 | Other: "List", 135 | }, &i18n.Message{ 136 | ID: "view", 137 | Other: "View", 138 | }, &i18n.Message{ 139 | ID: "run", 140 | Other: "Run ⏯ ", 141 | }, &i18n.Message{ 142 | ID: "set", 143 | Other: "Set 🛠 ", 144 | }, &i18n.Message{ 145 | ID: "clipboardBtn", 146 | Other: "Copy to clipboard", 147 | }, &i18n.Message{ 148 | ID: "out_dir", 149 | Other: "out dir:", 150 | }, &i18n.Message{ 151 | ID: "db_type", 152 | Other: " db type:", 153 | }, &i18n.Message{ 154 | ID: "db_host", 155 | Other: "db host:", 156 | }, &i18n.Message{ 157 | ID: "db_port", 158 | Other: "db port:", 159 | }, &i18n.Message{ 160 | ID: "db_usename", 161 | Other: "db username:", 162 | }, &i18n.Message{ 163 | ID: "db_pwd", 164 | Other: "db password:", 165 | }, &i18n.Message{ 166 | ID: "db_name", 167 | Other: "db name:", 168 | }, &i18n.Message{ 169 | ID: "is_dev", 170 | Other: "is dev:", 171 | }, &i18n.Message{ 172 | ID: "is_simple", 173 | Other: "is simple :", 174 | }, &i18n.Message{ 175 | ID: "is_out_sql", 176 | Other: "is out sql :", 177 | }, &i18n.Message{ 178 | ID: "is_out_func", 179 | Other: "is out func :", 180 | }, &i18n.Message{ 181 | ID: "is_foreign_key", 182 | Other: "is foreign key:", 183 | }, &i18n.Message{ 184 | ID: "is_gui", 185 | Other: "is show gui:", 186 | }, &i18n.Message{ 187 | ID: "is_table_name", 188 | Other: "is table name:", 189 | }, &i18n.Message{ 190 | ID: "url_tag", 191 | Other: "url tag:", 192 | }, &i18n.Message{ 193 | ID: "db_tag", 194 | Other: "db tag:", 195 | }, &i18n.Message{ 196 | ID: "language", 197 | Other: "Language:", 198 | }, &i18n.Message{ 199 | ID: "true", 200 | Other: "true", 201 | }, &i18n.Message{ 202 | ID: "false", 203 | Other: "false", 204 | }, &i18n.Message{ 205 | ID: "save", 206 | Other: "Save", 207 | }, &i18n.Message{ 208 | ID: "cancel", 209 | Other: "Cancel", 210 | }, &i18n.Message{ 211 | ID: "about", 212 | Other: "About", 213 | }, &i18n.Message{ 214 | ID: "log_run", 215 | Other: " Enter : run \n ↑ ↓: Selection of this view \n Tab : Multi view switching \n Ctrl+C : quit; \n Ctrl+Q : backup \n Mouse operation supported \n \n \033[33;7m Enter to execute \033[0m", 216 | }, &i18n.Message{ 217 | ID: "log_set", 218 | Other: " Enter : run \n ↑ ↓: Selection of this view \n Tab : Multi view switching \n Ctrl+C : quit \n Ctrl+Q : backup \n Mouse operation supported \n \n \033[33;7m Enter enter to open the settings window \033[0m", 219 | }) 220 | } 221 | -------------------------------------------------------------------------------- /data/dlg/mycui.go: -------------------------------------------------------------------------------- 1 | package dlg 2 | 3 | import ( 4 | "runtime" 5 | 6 | "github.com/xxjwxc/public/myi18n" 7 | ) 8 | 9 | // WinMain windows main loop 10 | func WinMain() { 11 | if runtime.GOOS == "windows" { 12 | myi18n.SetLocalLG("en") 13 | } 14 | OnInitDialog() 15 | } 16 | -------------------------------------------------------------------------------- /data/view/cnf/def.go: -------------------------------------------------------------------------------- 1 | package cnf 2 | 3 | // EImportsHead imports head options. import包含选项 4 | var EImportsHead = map[string]string{ 5 | "stirng": `"string"`, 6 | "time.Time": `"time"`, 7 | "gorm.Model": `"gorm.io/gorm"`, 8 | "fmt": `"fmt"`, 9 | "datatypes.JSON": `"gorm.io/datatypes"`, 10 | "datatypes.Date": `"gorm.io/datatypes"`, 11 | } 12 | 13 | // TypeMysqlDicMp Accurate matching type.精确匹配类型 14 | var TypeMysqlDicMp = map[string]string{ 15 | "smallint": "int16", 16 | "smallint unsigned": "uint16", 17 | "int": "int", 18 | "int unsigned": "uint", 19 | "bigint": "int64", 20 | "bigint unsigned": "uint64", 21 | "mediumint": "int32", 22 | "mediumint unsigned": "uint32", 23 | "varchar": "string", 24 | "char": "string", 25 | "date": "datatypes.Date", 26 | "datetime": "time.Time", 27 | "bit(1)": "[]uint8", 28 | "tinyint": "int8", 29 | "tinyint unsigned": "uint8", 30 | "tinyint(1)": "bool", // tinyint(1) 默认设置成bool 31 | "tinyint(1) unsigned": "bool", // tinyint(1) 默认设置成bool 32 | "json": "datatypes.JSON", 33 | "text": "string", 34 | "timestamp": "time.Time", 35 | "double": "float64", 36 | "double unsigned": "float64", 37 | "mediumtext": "string", 38 | "longtext": "string", 39 | "float": "float32", 40 | "float unsigned": "float32", 41 | "tinytext": "string", 42 | "enum": "string", 43 | "time": "time.Time", 44 | "tinyblob": "[]byte", 45 | "blob": "[]byte", 46 | "mediumblob": "[]byte", 47 | "longblob": "[]byte", 48 | "integer": "int64", 49 | "numeric": "float64", 50 | "smalldatetime": "time.Time", //sqlserver 51 | "nvarchar": "string", 52 | "real": "float32", 53 | "binary": "[]byte", 54 | "geometry": "[]byte", 55 | } 56 | 57 | // TypeMysqlMatchList Fuzzy Matching Types.模糊匹配类型 58 | var TypeMysqlMatchList = []struct { 59 | Key string 60 | Value string 61 | }{ 62 | {`^(tinyint)[(]\d+[)] unsigned`, "uint8"}, 63 | {`^(smallint)[(]\d+[)] unsigned`, "uint16"}, 64 | {`^(int)[(]\d+[)] unsigned`, "uint32"}, 65 | {`^(bigint)[(]\d+[)] unsigned`, "uint64"}, 66 | {`^(float)[(]\d+,\d+[)] unsigned`, "float64"}, 67 | {`^(double)[(]\d+,\d+[)] unsigned`, "float64"}, 68 | {`^(tinyint)[(]\d+[)]`, "int8"}, 69 | {`^(smallint)[(]\d+[)]`, "int16"}, 70 | {`^(int)[(]\d+[)]`, "int"}, 71 | {`^(bigint)[(]\d+[)]`, "int64"}, 72 | {`^(char)[(]\d+[)]`, "string"}, 73 | {`^(enum)[(](.)+[)]`, "string"}, 74 | {`^(varchar)[(]\d+[)]`, "string"}, 75 | {`^(varbinary)[(]\d+[)]`, "[]byte"}, 76 | {`^(blob)[(]\d+[)]`, "[]byte"}, 77 | {`^(binary)[(]\d+[)]`, "[]byte"}, 78 | {`^(decimal)[(]\d+,\d+[)]`, "float64"}, 79 | {`^(mediumint)[(]\d+[)]`, "int16"}, 80 | {`^(mediumint)[(]\d+[)] unsigned`, "uint16"}, 81 | {`^(double)[(]\d+,\d+[)]`, "float64"}, 82 | {`^(float)[(]\d+,\d+[)]`, "float64"}, 83 | {`^(datetime)[(]\d+[)]`, "time.Time"}, 84 | {`^(bit)[(]\d+[)]`, "[]uint8"}, 85 | {`^(text)[(]\d+[)]`, "string"}, 86 | {`^(integer)[(]\d+[)]`, "int"}, 87 | {`^(timestamp)[(]\d+[)]`, "time.Time"}, 88 | {`^(geometry)[(]\d+[)]`, "[]byte"}, 89 | {`^(set)[(][\s\S]+[)]`, "string"}, 90 | } 91 | -------------------------------------------------------------------------------- /data/view/generate/def.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | // interval.间隔 4 | var _interval = "\t" 5 | 6 | // IGenerate Generate Printing Interface.生成打印接口 7 | type IGenerate interface { 8 | // Get the generate data .获取结果数据 9 | Generate() string 10 | } 11 | 12 | // PrintAtom . atom print .原始打印 13 | type PrintAtom struct { 14 | lines []string 15 | } 16 | -------------------------------------------------------------------------------- /data/view/generate/generate.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import "github.com/xxjwxc/public/tools" 4 | 5 | // Add add one to print.打印 6 | func (p *PrintAtom) Add(str ...interface{}) { 7 | var tmp string 8 | for _, v := range str { 9 | tmp += tools.AsString(v) + _interval 10 | } 11 | p.lines = append(p.lines, tmp) 12 | } 13 | 14 | // Generates Get the generated list.获取生成列表 15 | func (p *PrintAtom) Generates() []string { 16 | return p.lines 17 | } 18 | -------------------------------------------------------------------------------- /data/view/genfunc/genfunc.go: -------------------------------------------------------------------------------- 1 | package genfunc 2 | 3 | // GetGenTableNameTemp get gen table template str 4 | func GetGenTableNameTemp() string { 5 | return genTnf 6 | } 7 | 8 | // GetGenColumnNameTemp get gen column template str 9 | func GetGenColumnNameTemp() string { 10 | return genColumn 11 | } 12 | 13 | // GetGenBaseTemp get gen base template str 14 | func GetGenBaseTemp() string { 15 | return genBase 16 | } 17 | 18 | // GetGenLogicTemp get gen logic template str 19 | func GetGenLogicTemp() string { 20 | return genlogic 21 | } 22 | 23 | // GetGenPreloadTemp get gen preload template str 24 | func GetGenPreloadTemp(multi bool) string { 25 | if multi { 26 | return genPreloadMulti 27 | } 28 | return genPreload 29 | } 30 | 31 | func GetGenPageTemp() string { 32 | return genPage 33 | } -------------------------------------------------------------------------------- /data/view/genfunc/genfunc_test.go: -------------------------------------------------------------------------------- 1 | package genfunc 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | 8 | "github.com/xxjwxc/gormt/data/view/genfunc/model" 9 | "github.com/xxjwxc/public/mysqldb" 10 | "gorm.io/gorm" 11 | 12 | "gorm.io/driver/mysql" 13 | ) 14 | 15 | /** 16 | 测试数据库地址:https://github.com/xxjwxc/gormt/blob/master/data/view/genfunc/model/matrix.sql 17 | */ 18 | 19 | func GetGorm(dataSourceName string) *gorm.DB { 20 | db, err := gorm.Open(mysql.Open(dataSourceName), &gorm.Config{PrepareStmt: false}) 21 | if err != nil { 22 | panic(err) 23 | } 24 | sqlDB, err := db.DB() 25 | if err != nil { 26 | panic(err) 27 | } 28 | // SetMaxIdleConns 设置空闲连接池中连接的最大数量 29 | sqlDB.SetMaxIdleConns(10) 30 | 31 | // SetMaxOpenConns 设置打开数据库连接的最大数量。 32 | sqlDB.SetMaxOpenConns(100) 33 | 34 | // SetConnMaxLifetime 设置了连接可复用的最大时间。 35 | sqlDB.SetConnMaxLifetime(time.Hour) 36 | 37 | return db.Debug() 38 | } 39 | 40 | // func NewDB(){ 41 | // db, _ := gorm.Open(...) 42 | // db.Model(&AAA).Where("aaa = ?", 2) 43 | // CallFunc(db) 44 | // } 45 | 46 | // func CallFunc(db *gorm.DB){ 47 | // // select a... 48 | // var bbb BBB 49 | // db.Table("bbb").Where("bbb = ?", 2).Find(&bbb)// in this case aaa = ? valid 50 | // // in this func how to us db to query BBB 51 | // } 52 | 53 | // TestFuncGet 测试条件获(Get/Gets) 54 | func TestFuncGet(t *testing.T) { 55 | model.OpenRelated() // 打开全局预加载 (外键) 56 | 57 | db := GetGorm("root:123456@tcp(127.0.0.1:3306)/matrix?charset=utf8&parseTime=True&loc=Local&interpolateParams=True") 58 | defer func() { 59 | sqldb, _ := db.DB() 60 | sqldb.Close() 61 | }() 62 | 63 | accountMgr := model.AccountMgr(db.Where("account_id = ?", 2)) 64 | account, err := accountMgr.Get() // 单条获取 65 | fmt.Println(err) 66 | fmt.Println(account) 67 | 68 | dbs := db.Where("name = ?", "bbbb") 69 | accountMgr.UpdateDB(dbs) // 更新数据库 70 | accounts, err := accountMgr.Gets() // 多个获取 71 | fmt.Println(err) 72 | fmt.Println(accounts) 73 | } 74 | 75 | // TestFuncOption 功能选项方式获取 76 | func TestFuncOption(t *testing.T) { 77 | // db := GetGorm("root:qwer@tcp(127.0.0.1:3306)/matrix?charset=utf8&parseTime=True&loc=Local&interpolateParams=True") 78 | // defer func() { 79 | // sqldb, _ := db.DB() 80 | // sqldb.Close() 81 | // }() 82 | orm := mysqldb.OnInitDBOrm("root:123456@tcp(127.0.0.1:3306)/matrix?charset=utf8&parseTime=True&loc=Local&interpolateParams=True", true) // 推荐方式 83 | defer orm.OnDestoryDB() 84 | db := orm.DB 85 | 86 | accountMgr := model.AccountMgr(db) 87 | accountMgr.SetIsRelated(true) // 打开预加载 (外键) 88 | account, err := accountMgr.GetByOption(accountMgr.WithID(1), accountMgr.WithUserID(1)) // 多case条件获取单个 89 | fmt.Println(err) 90 | fmt.Println(account) 91 | 92 | accounts, err := accountMgr.GetByOptions(accountMgr.WithName("bbbb")) // 多功能选项获取 93 | fmt.Println(err) 94 | fmt.Println(accounts) 95 | } 96 | 97 | // TestFuncFrom 单元素方式获取 98 | func TestFuncFrom(t *testing.T) { 99 | db := GetGorm("root:qwer@tcp(127.0.0.1:3306)/matrix?charset=utf8&parseTime=True&loc=Local&interpolateParams=True") 100 | defer func() { 101 | sqldb, _ := db.DB() 102 | sqldb.Close() 103 | }() 104 | 105 | accountMgr := model.AccountMgr(db) 106 | accountMgr.SetIsRelated(true) // 打开预加载 (外键) 107 | 108 | account, err := accountMgr.GetFromAccountID(2) 109 | fmt.Println(err) 110 | fmt.Println(account) 111 | 112 | accounts, err := accountMgr.GetFromName("bbbb") 113 | fmt.Println(err) 114 | fmt.Println(accounts) 115 | } 116 | 117 | // TestFuncFetchBy 索引方式获取 118 | func TestFuncFetchBy(t *testing.T) { 119 | db := GetGorm("root:qwer@tcp(127.0.0.1:3306)/matrix?charset=utf8&parseTime=True&loc=Local&interpolateParams=True") 120 | defer func() { 121 | sqldb, _ := db.DB() 122 | sqldb.Close() 123 | }() 124 | 125 | accountMgr := model.AccountMgr(db) 126 | accountMgr.SetIsRelated(true) // 打开预加载 (外键) 127 | 128 | account, err := accountMgr.FetchByPrimaryKey(2) // primary key 129 | fmt.Println(err) 130 | fmt.Println(account) 131 | 132 | account1, err := accountMgr.FetchUniqueIndexByAccount(2, 2) // unique index 133 | fmt.Println(err) 134 | fmt.Println(account1) 135 | 136 | accounts, err := accountMgr.FetchIndexByTp(2, 2) 137 | fmt.Println(err) 138 | fmt.Println(accounts) 139 | } 140 | 141 | // TestCondition 测试sql构建 142 | func TestCondition(t *testing.T) { 143 | condition := model.Condition{} 144 | condition.And(model.AccountColumns.AccountID, ">=", "1") 145 | condition.And(model.AccountColumns.UserID, "in", []string{"1", "2", "3"}) 146 | condition.AndWithCondition(false, model.AccountColumns.AccountID, "in", []string{"5"}) 147 | condition.Or(model.AccountColumns.Type, "in", []string{"1", "2", "3"}) 148 | 149 | where, obj := condition.Get() 150 | fmt.Println(where) 151 | fmt.Println(obj...) 152 | 153 | db := GetGorm("root:qwer@tcp(127.0.0.1:3306)/matrix?charset=utf8&parseTime=True&loc=Local&interpolateParams=True") 154 | defer func() { 155 | sqldb, _ := db.DB() 156 | sqldb.Close() 157 | }() 158 | 159 | accountMgr := model.AccountMgr(db.Where(where, obj...)) 160 | accountMgr.Gets() 161 | } 162 | -------------------------------------------------------------------------------- /data/view/genfunc/model/gen.base.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | 8 | "gorm.io/gorm" 9 | ) 10 | 11 | var globalIsRelated bool = true // 全局预加载 12 | 13 | // prepare for other 14 | type _BaseMgr struct { 15 | *gorm.DB 16 | ctx context.Context 17 | cancel context.CancelFunc 18 | timeout time.Duration 19 | isRelated bool 20 | } 21 | 22 | // SetCtx set context 23 | func (obj *_BaseMgr) SetTimeOut(timeout time.Duration) { 24 | obj.ctx, obj.cancel = context.WithTimeout(context.Background(), timeout) 25 | obj.timeout = timeout 26 | } 27 | 28 | // SetCtx set context 29 | func (obj *_BaseMgr) SetCtx(c context.Context) { 30 | if c != nil { 31 | obj.ctx = c 32 | } 33 | } 34 | 35 | // Ctx get context 36 | func (obj *_BaseMgr) GetCtx() context.Context { 37 | return obj.ctx 38 | } 39 | 40 | // Cancel cancel context 41 | func (obj *_BaseMgr) Cancel(c context.Context) { 42 | obj.cancel() 43 | } 44 | 45 | // GetDB get gorm.DB info 46 | func (obj *_BaseMgr) GetDB() *gorm.DB { 47 | return obj.DB 48 | } 49 | 50 | // UpdateDB update gorm.DB info 51 | func (obj *_BaseMgr) UpdateDB(db *gorm.DB) { 52 | obj.DB = db 53 | } 54 | 55 | // GetIsRelated Query foreign key Association.获取是否查询外键关联(gorm.Related) 56 | func (obj *_BaseMgr) GetIsRelated() bool { 57 | return obj.isRelated 58 | } 59 | 60 | // SetIsRelated Query foreign key Association.设置是否查询外键关联(gorm.Related) 61 | func (obj *_BaseMgr) SetIsRelated(b bool) { 62 | obj.isRelated = b 63 | } 64 | 65 | // New new gorm.新gorm 66 | func (obj *_BaseMgr) New() *gorm.DB { 67 | return obj.DB.Session(&gorm.Session{Context: obj.ctx}) 68 | } 69 | 70 | type options struct { 71 | query map[string]interface{} 72 | } 73 | 74 | // Option overrides behavior of Connect. 75 | type Option interface { 76 | apply(*options) 77 | } 78 | 79 | type optionFunc func(*options) 80 | 81 | func (f optionFunc) apply(o *options) { 82 | f(o) 83 | } 84 | 85 | // OpenRelated 打开全局预加载 86 | func OpenRelated() { 87 | globalIsRelated = true 88 | } 89 | 90 | // CloseRelated 关闭全局预加载 91 | func CloseRelated() { 92 | globalIsRelated = true 93 | } 94 | 95 | // 自定义sql查询 96 | type Condition struct { 97 | list []*conditionInfo 98 | } 99 | 100 | func (c *Condition) AndWithCondition(condition bool, column string, cases string, value interface{}) (*Condition) { 101 | if condition { 102 | c.list = append(c.list, &conditionInfo{ 103 | andor: "and", 104 | column: column, // 列名 105 | case_: cases, // 条件(and,or,in,>=,<=) 106 | value: value, 107 | }) 108 | } 109 | return c 110 | } 111 | 112 | // And a Condition by and .and 一个条件 113 | func (c *Condition) And(column string, cases string, value interface{})(*Condition) { 114 | return c.AndWithCondition(true, column, cases, value) 115 | } 116 | 117 | func (c *Condition) OrWithCondition(condition bool, column string, cases string, value interface{}) (*Condition){ 118 | if condition { 119 | c.list = append(c.list, &conditionInfo{ 120 | andor: "or", 121 | column: column, // 列名 122 | case_: cases, // 条件(and,or,in,>=,<=) 123 | value: value, 124 | }) 125 | } 126 | return c 127 | } 128 | 129 | // Or a Condition by or .or 一个条件 130 | func (c *Condition) Or(column string, cases string, value interface{})(*Condition) { 131 | return c.OrWithCondition(true, column, cases, value) 132 | } 133 | 134 | func (c *Condition) Get() (where string, out []interface{}) { 135 | firstAnd := -1 136 | for i := 0; i < len(c.list); i++ { // 查找第一个and 137 | if c.list[i].andor == "and" { 138 | where = fmt.Sprintf("`%v` %v ?", c.list[i].column, c.list[i].case_) 139 | out = append(out, c.list[i].value) 140 | firstAnd = i 141 | break 142 | } 143 | } 144 | 145 | if firstAnd < 0 && len(c.list) > 0 { // 补刀 146 | where = fmt.Sprintf("`%v` %v ?", c.list[0].column, c.list[0].case_) 147 | out = append(out, c.list[0].value) 148 | firstAnd = 0 149 | } 150 | 151 | for i := 0; i < len(c.list); i++ { // 添加剩余的 152 | if firstAnd != i { 153 | where += fmt.Sprintf(" %v `%v` %v ?", c.list[i].andor, c.list[i].column, c.list[i].case_) 154 | out = append(out, c.list[i].value) 155 | } 156 | } 157 | 158 | return 159 | } 160 | 161 | type conditionInfo struct { 162 | andor string 163 | column string // 列名 164 | case_ string // 条件(in,>=,<=) 165 | value interface{} 166 | } 167 | -------------------------------------------------------------------------------- /data/view/genfunc/model/matrix.gen.account.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "gorm.io/gorm" 7 | ) 8 | 9 | type _AccountMgr struct { 10 | *_BaseMgr 11 | } 12 | 13 | // AccountMgr open func 14 | func AccountMgr(db *gorm.DB) *_AccountMgr { 15 | if db == nil { 16 | panic(fmt.Errorf("AccountMgr need init by db")) 17 | } 18 | ctx, cancel := context.WithCancel(context.Background()) 19 | return &_AccountMgr{_BaseMgr: &_BaseMgr{DB: db.Model(Account{}), isRelated: globalIsRelated, ctx: ctx, cancel: cancel, timeout: -1}} 20 | } 21 | 22 | // GetTableName get sql table name.获取数据库名字 23 | func (obj *_AccountMgr) GetTableName() string { 24 | return "account" 25 | } 26 | 27 | // Get 获取 28 | func (obj *_AccountMgr) Get() (result Account, err error) { 29 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Find(&result).Error 30 | if err == nil && obj.isRelated { 31 | if err = obj.New().Table("user").Where("user_id = ?", result.UserID).Find(&result.User).Error; err != nil { // 32 | if err != gorm.ErrRecordNotFound { // 非 没找到 33 | return 34 | } 35 | } 36 | } 37 | 38 | return 39 | } 40 | 41 | // Gets 获取批量结果 42 | func (obj *_AccountMgr) Gets() (results []*Account, err error) { 43 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Find(&results).Error 44 | if err == nil && obj.isRelated { 45 | for i := 0; i < len(results); i++ { 46 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 47 | if err != gorm.ErrRecordNotFound { // 非 没找到 48 | return 49 | } 50 | } 51 | } 52 | } 53 | return 54 | } 55 | 56 | //////////////////////////option case //////////////////////////////////////////// 57 | 58 | // WithID id获取 59 | func (obj *_AccountMgr) WithID(id int) Option { 60 | return optionFunc(func(o *options) { o.query["id"] = id }) 61 | } 62 | 63 | // WithAccountID account_id获取 64 | func (obj *_AccountMgr) WithAccountID(accountID int) Option { 65 | return optionFunc(func(o *options) { o.query["account_id"] = accountID }) 66 | } 67 | 68 | // WithUserID user_id获取 69 | func (obj *_AccountMgr) WithUserID(userID int) Option { 70 | return optionFunc(func(o *options) { o.query["user_id"] = userID }) 71 | } 72 | 73 | // WithType type获取 74 | func (obj *_AccountMgr) WithType(_type int) Option { 75 | return optionFunc(func(o *options) { o.query["type"] = _type }) 76 | } 77 | 78 | // WithName name获取 79 | func (obj *_AccountMgr) WithName(name string) Option { 80 | return optionFunc(func(o *options) { o.query["name"] = name }) 81 | } 82 | 83 | // GetByOption 功能选项模式获取 84 | func (obj *_AccountMgr) GetByOption(opts ...Option) (result Account, err error) { 85 | options := options{ 86 | query: make(map[string]interface{}, len(opts)), 87 | } 88 | for _, o := range opts { 89 | o.apply(&options) 90 | } 91 | 92 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where(options.query).Find(&result).Error 93 | if err == nil && obj.isRelated { 94 | if err = obj.New().Table("user").Where("user_id = ?", result.UserID).Find(&result.User).Error; err != nil { // 95 | if err != gorm.ErrRecordNotFound { // 非 没找到 96 | return 97 | } 98 | } 99 | } 100 | 101 | return 102 | } 103 | 104 | // GetByOptions 批量功能选项模式获取 105 | func (obj *_AccountMgr) GetByOptions(opts ...Option) (results []*Account, err error) { 106 | options := options{ 107 | query: make(map[string]interface{}, len(opts)), 108 | } 109 | for _, o := range opts { 110 | o.apply(&options) 111 | } 112 | 113 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where(options.query).Find(&results).Error 114 | if err == nil && obj.isRelated { 115 | for i := 0; i < len(results); i++ { 116 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 117 | if err != gorm.ErrRecordNotFound { // 非 没找到 118 | return 119 | } 120 | } 121 | } 122 | } 123 | return 124 | } 125 | 126 | //////////////////////////enume case //////////////////////////////////////////// 127 | 128 | // GetFromID 通过id获取内容 129 | func (obj *_AccountMgr) GetFromID(id int) (result Account, err error) { 130 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`id` = ?", id).Find(&result).Error 131 | if err == nil && obj.isRelated { 132 | if err = obj.New().Table("user").Where("user_id = ?", result.UserID).Find(&result.User).Error; err != nil { // 133 | if err != gorm.ErrRecordNotFound { // 非 没找到 134 | return 135 | } 136 | } 137 | } 138 | 139 | return 140 | } 141 | 142 | // GetBatchFromID 批量查找 143 | func (obj *_AccountMgr) GetBatchFromID(ids []int) (results []*Account, err error) { 144 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`id` IN (?)", ids).Find(&results).Error 145 | if err == nil && obj.isRelated { 146 | for i := 0; i < len(results); i++ { 147 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 148 | if err != gorm.ErrRecordNotFound { // 非 没找到 149 | return 150 | } 151 | } 152 | } 153 | } 154 | return 155 | } 156 | 157 | // GetFromAccountID 通过account_id获取内容 158 | func (obj *_AccountMgr) GetFromAccountID(accountID int) (results []*Account, err error) { 159 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`account_id` = ?", accountID).Find(&results).Error 160 | if err == nil && obj.isRelated { 161 | for i := 0; i < len(results); i++ { 162 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 163 | if err != gorm.ErrRecordNotFound { // 非 没找到 164 | return 165 | } 166 | } 167 | } 168 | } 169 | return 170 | } 171 | 172 | // GetBatchFromAccountID 批量查找 173 | func (obj *_AccountMgr) GetBatchFromAccountID(accountIDs []int) (results []*Account, err error) { 174 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`account_id` IN (?)", accountIDs).Find(&results).Error 175 | if err == nil && obj.isRelated { 176 | for i := 0; i < len(results); i++ { 177 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 178 | if err != gorm.ErrRecordNotFound { // 非 没找到 179 | return 180 | } 181 | } 182 | } 183 | } 184 | return 185 | } 186 | 187 | // GetFromUserID 通过user_id获取内容 188 | func (obj *_AccountMgr) GetFromUserID(userID int) (results []*Account, err error) { 189 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`user_id` = ?", userID).Find(&results).Error 190 | if err == nil && obj.isRelated { 191 | for i := 0; i < len(results); i++ { 192 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 193 | if err != gorm.ErrRecordNotFound { // 非 没找到 194 | return 195 | } 196 | } 197 | } 198 | } 199 | return 200 | } 201 | 202 | // GetBatchFromUserID 批量查找 203 | func (obj *_AccountMgr) GetBatchFromUserID(userIDs []int) (results []*Account, err error) { 204 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`user_id` IN (?)", userIDs).Find(&results).Error 205 | if err == nil && obj.isRelated { 206 | for i := 0; i < len(results); i++ { 207 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 208 | if err != gorm.ErrRecordNotFound { // 非 没找到 209 | return 210 | } 211 | } 212 | } 213 | } 214 | return 215 | } 216 | 217 | // GetFromType 通过type获取内容 218 | func (obj *_AccountMgr) GetFromType(_type int) (results []*Account, err error) { 219 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`type` = ?", _type).Find(&results).Error 220 | if err == nil && obj.isRelated { 221 | for i := 0; i < len(results); i++ { 222 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 223 | if err != gorm.ErrRecordNotFound { // 非 没找到 224 | return 225 | } 226 | } 227 | } 228 | } 229 | return 230 | } 231 | 232 | // GetBatchFromType 批量查找 233 | func (obj *_AccountMgr) GetBatchFromType(_types []int) (results []*Account, err error) { 234 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`type` IN (?)", _types).Find(&results).Error 235 | if err == nil && obj.isRelated { 236 | for i := 0; i < len(results); i++ { 237 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 238 | if err != gorm.ErrRecordNotFound { // 非 没找到 239 | return 240 | } 241 | } 242 | } 243 | } 244 | return 245 | } 246 | 247 | // GetFromName 通过name获取内容 248 | func (obj *_AccountMgr) GetFromName(name string) (results []*Account, err error) { 249 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`name` = ?", name).Find(&results).Error 250 | if err == nil && obj.isRelated { 251 | for i := 0; i < len(results); i++ { 252 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 253 | if err != gorm.ErrRecordNotFound { // 非 没找到 254 | return 255 | } 256 | } 257 | } 258 | } 259 | return 260 | } 261 | 262 | // GetBatchFromName 批量查找 263 | func (obj *_AccountMgr) GetBatchFromName(names []string) (results []*Account, err error) { 264 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`name` IN (?)", names).Find(&results).Error 265 | if err == nil && obj.isRelated { 266 | for i := 0; i < len(results); i++ { 267 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 268 | if err != gorm.ErrRecordNotFound { // 非 没找到 269 | return 270 | } 271 | } 272 | } 273 | } 274 | return 275 | } 276 | 277 | //////////////////////////primary index case //////////////////////////////////////////// 278 | 279 | // FetchByPrimaryKey primary or index 获取唯一内容 280 | func (obj *_AccountMgr) FetchByPrimaryKey(id int) (result Account, err error) { 281 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`id` = ?", id).Find(&result).Error 282 | if err == nil && obj.isRelated { 283 | if err = obj.New().Table("user").Where("user_id = ?", result.UserID).Find(&result.User).Error; err != nil { // 284 | if err != gorm.ErrRecordNotFound { // 非 没找到 285 | return 286 | } 287 | } 288 | } 289 | 290 | return 291 | } 292 | 293 | // FetchUniqueIndexByAccount primary or index 获取唯一内容 294 | func (obj *_AccountMgr) FetchUniqueIndexByAccount(accountID int, userID int) (result Account, err error) { 295 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`account_id` = ? AND `user_id` = ?", accountID, userID).Find(&result).Error 296 | if err == nil && obj.isRelated { 297 | if err = obj.New().Table("user").Where("user_id = ?", result.UserID).Find(&result.User).Error; err != nil { // 298 | if err != gorm.ErrRecordNotFound { // 非 没找到 299 | return 300 | } 301 | } 302 | } 303 | 304 | return 305 | } 306 | 307 | // FetchIndexByTp 获取多个内容 308 | func (obj *_AccountMgr) FetchIndexByTp(userID int, _type int) (results []*Account, err error) { 309 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`user_id` = ? AND `type` = ?", userID, _type).Find(&results).Error 310 | if err == nil && obj.isRelated { 311 | for i := 0; i < len(results); i++ { 312 | if err = obj.New().Table("user").Where("user_id = ?", results[i].UserID).Find(&results[i].User).Error; err != nil { // 313 | if err != gorm.ErrRecordNotFound { // 非 没找到 314 | return 315 | } 316 | } 317 | } 318 | } 319 | return 320 | } 321 | -------------------------------------------------------------------------------- /data/view/genfunc/model/matrix.gen.user.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "gorm.io/gorm" 7 | ) 8 | 9 | type _UserMgr struct { 10 | *_BaseMgr 11 | } 12 | 13 | // UserMgr open func 14 | func UserMgr(db *gorm.DB) *_UserMgr { 15 | if db == nil { 16 | panic(fmt.Errorf("UserMgr need init by db")) 17 | } 18 | ctx, cancel := context.WithCancel(context.Background()) 19 | return &_UserMgr{_BaseMgr: &_BaseMgr{DB: db.Model(User{}), isRelated: globalIsRelated, ctx: ctx, cancel: cancel, timeout: -1}} 20 | } 21 | 22 | // GetTableName get sql table name.获取数据库名字 23 | func (obj *_UserMgr) GetTableName() string { 24 | return "user" 25 | } 26 | 27 | // Get 获取 28 | func (obj *_UserMgr) Get() (result User, err error) { 29 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Find(&result).Error 30 | 31 | return 32 | } 33 | 34 | // Gets 获取批量结果 35 | func (obj *_UserMgr) Gets() (results []*User, err error) { 36 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Find(&results).Error 37 | 38 | return 39 | } 40 | 41 | //////////////////////////option case //////////////////////////////////////////// 42 | 43 | // WithUserID user_id获取 44 | func (obj *_UserMgr) WithUserID(userID int) Option { 45 | return optionFunc(func(o *options) { o.query["user_id"] = userID }) 46 | } 47 | 48 | // WithName name获取 49 | func (obj *_UserMgr) WithName(name string) Option { 50 | return optionFunc(func(o *options) { o.query["name"] = name }) 51 | } 52 | 53 | // WithSex sex获取 54 | func (obj *_UserMgr) WithSex(sex int) Option { 55 | return optionFunc(func(o *options) { o.query["sex"] = sex }) 56 | } 57 | 58 | // WithJob job获取 59 | func (obj *_UserMgr) WithJob(job int) Option { 60 | return optionFunc(func(o *options) { o.query["job"] = job }) 61 | } 62 | 63 | // GetByOption 功能选项模式获取 64 | func (obj *_UserMgr) GetByOption(opts ...Option) (result User, err error) { 65 | options := options{ 66 | query: make(map[string]interface{}, len(opts)), 67 | } 68 | for _, o := range opts { 69 | o.apply(&options) 70 | } 71 | 72 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where(options.query).Find(&result).Error 73 | 74 | return 75 | } 76 | 77 | // GetByOptions 批量功能选项模式获取 78 | func (obj *_UserMgr) GetByOptions(opts ...Option) (results []*User, err error) { 79 | options := options{ 80 | query: make(map[string]interface{}, len(opts)), 81 | } 82 | for _, o := range opts { 83 | o.apply(&options) 84 | } 85 | 86 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where(options.query).Find(&results).Error 87 | 88 | return 89 | } 90 | 91 | //////////////////////////enume case //////////////////////////////////////////// 92 | 93 | // GetFromUserID 通过user_id获取内容 94 | func (obj *_UserMgr) GetFromUserID(userID int) (result User, err error) { 95 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`user_id` = ?", userID).Find(&result).Error 96 | 97 | return 98 | } 99 | 100 | // GetBatchFromUserID 批量查找 101 | func (obj *_UserMgr) GetBatchFromUserID(userIDs []int) (results []*User, err error) { 102 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`user_id` IN (?)", userIDs).Find(&results).Error 103 | 104 | return 105 | } 106 | 107 | // GetFromName 通过name获取内容 108 | func (obj *_UserMgr) GetFromName(name string) (results []*User, err error) { 109 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`name` = ?", name).Find(&results).Error 110 | 111 | return 112 | } 113 | 114 | // GetBatchFromName 批量查找 115 | func (obj *_UserMgr) GetBatchFromName(names []string) (results []*User, err error) { 116 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`name` IN (?)", names).Find(&results).Error 117 | 118 | return 119 | } 120 | 121 | // GetFromSex 通过sex获取内容 122 | func (obj *_UserMgr) GetFromSex(sex int) (results []*User, err error) { 123 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`sex` = ?", sex).Find(&results).Error 124 | 125 | return 126 | } 127 | 128 | // GetBatchFromSex 批量查找 129 | func (obj *_UserMgr) GetBatchFromSex(sexs []int) (results []*User, err error) { 130 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`sex` IN (?)", sexs).Find(&results).Error 131 | 132 | return 133 | } 134 | 135 | // GetFromJob 通过job获取内容 136 | func (obj *_UserMgr) GetFromJob(job int) (results []*User, err error) { 137 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`job` = ?", job).Find(&results).Error 138 | 139 | return 140 | } 141 | 142 | // GetBatchFromJob 批量查找 143 | func (obj *_UserMgr) GetBatchFromJob(jobs []int) (results []*User, err error) { 144 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`job` IN (?)", jobs).Find(&results).Error 145 | 146 | return 147 | } 148 | 149 | //////////////////////////primary index case //////////////////////////////////////////// 150 | 151 | // FetchByPrimaryKey primary or index 获取唯一内容 152 | func (obj *_UserMgr) FetchByPrimaryKey(userID int) (result User, err error) { 153 | err = obj.DB.WithContext(obj.ctx).Table(obj.GetTableName()).Where("`user_id` = ?", userID).Find(&result).Error 154 | 155 | return 156 | } 157 | -------------------------------------------------------------------------------- /data/view/genfunc/model/matrix.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | // Account [...] 4 | type Account struct { 5 | ID int `gorm:"primaryKey;column:id;type:int(11);not null" json:"-"` 6 | AccountID int `gorm:"uniqueIndex:account;column:account_id;type:int(11)" json:"accountId"` 7 | UserID int `gorm:"uniqueIndex:account;index:tp;column:user_id;type:int(11)" json:"userId"` 8 | User User `gorm:"joinForeignKey:user_id;foreignKey:user_id" json:"userList"` 9 | Type int `gorm:"index:tp;column:type;type:int(11)" json:"type"` 10 | Name string `gorm:"column:name;type:varchar(255)" json:"name"` 11 | } 12 | 13 | // TableName get sql table name.获取数据库表名 14 | func (m *Account) TableName() string { 15 | return "account" 16 | } 17 | 18 | // AccountColumns get sql column name.获取数据库列名 19 | var AccountColumns = struct { 20 | ID string 21 | AccountID string 22 | UserID string 23 | Type string 24 | Name string 25 | }{ 26 | ID: "id", 27 | AccountID: "account_id", 28 | UserID: "user_id", 29 | Type: "type", 30 | Name: "name", 31 | } 32 | 33 | // User [...] 34 | type User struct { 35 | UserID int `gorm:"primaryKey;column:user_id;type:int(11);not null" json:"-"` 36 | Name string `gorm:"column:name;type:varchar(30);not null" json:"name"` 37 | Sex int `gorm:"column:sex;type:int(11);not null" json:"sex"` 38 | Job int `gorm:"column:job;type:int(11);not null" json:"job"` 39 | } 40 | 41 | // TableName get sql table name.获取数据库表名 42 | func (m *User) TableName() string { 43 | return "user" 44 | } 45 | 46 | // UserColumns get sql column name.获取数据库列名 47 | var UserColumns = struct { 48 | UserID string 49 | Name string 50 | Sex string 51 | Job string 52 | }{ 53 | UserID: "user_id", 54 | Name: "name", 55 | Sex: "sex", 56 | Job: "job", 57 | } 58 | -------------------------------------------------------------------------------- /data/view/genfunc/model/matrix.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : localhost 5 | Source Server Type : MySQL 6 | Source Server Version : 80017 7 | Source Host : localhost:3306 8 | Source Schema : matrix 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 80017 12 | File Encoding : 65001 13 | 14 | Date: 12/01/2020 21:35:09 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for account 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `account`; 24 | CREATE TABLE `account` ( 25 | `id` int(11) NOT NULL AUTO_INCREMENT, 26 | `account_id` int(11) DEFAULT NULL, 27 | `user_id` int(11) DEFAULT NULL, 28 | `type` int(11) DEFAULT NULL, 29 | `name` varchar(255) DEFAULT NULL, 30 | PRIMARY KEY (`id`), 31 | UNIQUE KEY `account` (`account_id`,`user_id`), 32 | KEY `tp` (`user_id`,`type`), 33 | CONSTRAINT `account_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) 34 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; 35 | 36 | -- ---------------------------- 37 | -- Records of account 38 | -- ---------------------------- 39 | BEGIN; 40 | INSERT INTO `account` VALUES (1, 1, 1, 1, 'aaaa'); 41 | INSERT INTO `account` VALUES (2, 2, 2, 2, 'bbbb'); 42 | INSERT INTO `account` VALUES (3, 3, 2, 2, 'bbbb'); 43 | COMMIT; 44 | 45 | -- ---------------------------- 46 | -- Table structure for user 47 | -- ---------------------------- 48 | DROP TABLE IF EXISTS `user`; 49 | CREATE TABLE `user` ( 50 | `user_id` int(11) NOT NULL AUTO_INCREMENT, 51 | `name` varchar(30) NOT NULL, 52 | `sex` int(11) NOT NULL, 53 | `job` int(11) NOT NULL, 54 | PRIMARY KEY (`user_id`) USING BTREE 55 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; 56 | 57 | -- ---------------------------- 58 | -- Records of user 59 | -- ---------------------------- 60 | BEGIN; 61 | INSERT INTO `user` VALUES (1, 'xxj1', 1, 1); 62 | INSERT INTO `user` VALUES (2, 'xxj2', 2, 2); 63 | INSERT INTO `user` VALUES (3, 'xxj3', 3, 3); 64 | COMMIT; 65 | 66 | SET FOREIGN_KEY_CHECKS = 1; 67 | -------------------------------------------------------------------------------- /data/view/genstruct/common.go: -------------------------------------------------------------------------------- 1 | package genstruct 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "sort" 7 | "strings" 8 | "text/template" 9 | 10 | "github.com/xxjwxc/gormt/data/config" 11 | "github.com/xxjwxc/gormt/data/view/cnf" 12 | "github.com/xxjwxc/gormt/data/view/generate" 13 | "github.com/xxjwxc/gormt/data/view/genfunc" 14 | ) 15 | 16 | // SetName Setting element name.设置元素名字 17 | func (e *GenElement) SetName(name string) { 18 | e.Name = name 19 | } 20 | 21 | // SetType Setting element type.设置元素类型 22 | func (e *GenElement) SetType(tp string) { 23 | e.Type = tp 24 | } 25 | 26 | // SetNotes Setting element notes.设置注释 27 | func (e *GenElement) SetNotes(notes string) { 28 | e.Notes = strings.Replace(notes, "\n", ",", -1) 29 | } 30 | 31 | // AddTag Add a tag .添加一个tag标记 32 | func (e *GenElement) AddTag(k string, v string) { 33 | if e.Tags == nil { 34 | e.Tags = make(map[string][]string) 35 | } 36 | e.Tags[k] = append(e.Tags[k], v) 37 | } 38 | 39 | // Generate Get the result data.获取结果数据 40 | func (e *GenElement) Generate() string { 41 | tag := "" 42 | if e.Tags != nil { 43 | var ks []string 44 | for k := range e.Tags { 45 | ks = append(ks, k) 46 | } 47 | sort.Strings(ks) 48 | 49 | var tags []string 50 | for _, v := range ks { 51 | tags = append(tags, fmt.Sprintf(`%v:"%v"`, v, strings.Join(e.Tags[v], ";"))) 52 | } 53 | tag = fmt.Sprintf("`%v`", strings.Join(tags, " ")) 54 | } 55 | 56 | var p generate.PrintAtom 57 | if len(e.Notes) > 0 { 58 | p.Add(e.Name, e.Type, tag, "// "+e.Notes) 59 | } else { 60 | p.Add(e.Name, e.Type, tag) 61 | } 62 | 63 | return p.Generates()[0] 64 | } 65 | 66 | // GenerateColor Get the result data.获取结果数据 67 | func (e *GenElement) GenerateColor() string { 68 | tag := "" 69 | if e.Tags != nil { 70 | var ks []string 71 | for k := range e.Tags { 72 | ks = append(ks, k) 73 | } 74 | sort.Strings(ks) 75 | 76 | var tags []string 77 | for _, v := range ks { 78 | tags = append(tags, fmt.Sprintf(`%v:"%v"`, v, strings.Join(e.Tags[v], ";"))) 79 | } 80 | tag = fmt.Sprintf("`%v`", strings.Join(tags, " ")) 81 | } 82 | 83 | var p generate.PrintAtom 84 | if len(e.Notes) > 0 { 85 | p.Add(e.Name, "\033[32;1m "+e.Type+" \033[0m", "\033[31;1m "+tag+" \033[0m", "\033[32;1m // "+e.Notes+" \033[0m") 86 | } else { 87 | p.Add(e.Name, "\033[32;1m "+e.Type+" \033[0m", "\033[31;1m "+tag+" \033[0m") 88 | } 89 | 90 | return p.Generates()[0] 91 | } 92 | 93 | ////////////////////////////////////////////////////////////////////////////// 94 | // struct 95 | ////////////////////////////////////////////////////////////////////////////// 96 | 97 | // SetCreatTableStr Set up SQL create statement, backup use setup create statement, backup use.设置创建语句,备份使用 98 | func (s *GenStruct) SetCreatTableStr(sql string) { 99 | s.SQLBuildStr = sql 100 | } 101 | 102 | // SetTableName Setting the name of struct.设置struct名字 103 | func (s *GenStruct) SetTableName(name string) { 104 | s.TableName = name 105 | } 106 | 107 | // SetStructName Setting the name of struct.设置struct名字 108 | func (s *GenStruct) SetStructName(name string) { 109 | s.Name = name 110 | } 111 | 112 | // SetNotes set the notes.设置注释 113 | func (s *GenStruct) SetNotes(notes string) { 114 | if len(notes) == 0 { 115 | notes = "[...]" // default of struct notes(for export ).struct 默认注释(为了导出注释) 116 | } 117 | 118 | notes = s.Name + " " + notes 119 | 120 | a := strings.Split(notes, "\n") 121 | var text []string 122 | 123 | for _, v := range a { 124 | // if len(v) > 0 { 125 | text = append(text, "// "+v) 126 | // } 127 | } 128 | s.Notes = strings.Join(text, ";") 129 | } 130 | 131 | // AddElement Add one or more elements.添加一个/或多个元素 132 | func (s *GenStruct) AddElement(e ...GenElement) { 133 | s.Em = append(s.Em, e...) 134 | } 135 | 136 | // GenerateTableName generate table name .生成表名 137 | func (s *GenStruct) GenerateTableName() []string { 138 | tmpl, err := template.New("gen_tnf").Parse(genfunc.GetGenTableNameTemp()) 139 | if err != nil { 140 | panic(err) 141 | } 142 | var data struct { 143 | TableName string 144 | StructName string 145 | } 146 | data.TableName, data.StructName = s.TableName, s.Name 147 | var buf bytes.Buffer 148 | tmpl.Execute(&buf, data) 149 | return []string{buf.String()} 150 | } 151 | 152 | // GenerateColumnName generate column name . 生成列名 153 | func (s *GenStruct) GenerateColumnName() []string { 154 | tmpl, err := template.New("gen_tnc").Parse(genfunc.GetGenColumnNameTemp()) 155 | if err != nil { 156 | panic(err) 157 | } 158 | var data struct { 159 | StructName string 160 | Em []struct { 161 | ColumnName string 162 | StructName string 163 | } 164 | } 165 | data.StructName = s.Name 166 | for _, v := range s.Em { 167 | if strings.EqualFold(v.Type, "gorm.Model") { // gorm model 168 | data.Em = append(data.Em, []struct { 169 | ColumnName string 170 | StructName string 171 | }{ 172 | {ColumnName: "id", StructName: "ID"}, 173 | {ColumnName: "created_at", StructName: "CreatedAt"}, 174 | {ColumnName: "updated_at", StructName: "UpdatedAt"}, 175 | {ColumnName: "deleted_at", StructName: "DeletedAt"}, 176 | }...) 177 | } else if len(v.ColumnName) > 0 { 178 | data.Em = append(data.Em, struct { 179 | ColumnName string 180 | StructName string 181 | }{ColumnName: v.ColumnName, 182 | StructName: v.Name, 183 | }) 184 | } 185 | 186 | } 187 | 188 | var buf bytes.Buffer 189 | tmpl.Execute(&buf, data) 190 | return []string{buf.String()} 191 | } 192 | 193 | // Generates Get the result data.获取结果数据 194 | func (s *GenStruct) Generates() []string { 195 | var p generate.PrintAtom 196 | if config.GetIsOutSQL() { 197 | p.Add("/******sql******") 198 | p.Add(s.SQLBuildStr) 199 | p.Add("******sql******/") 200 | } 201 | p.Add(s.Notes) 202 | p.Add("type", s.Name, "struct {") 203 | mp := make(map[string]bool, len(s.Em)) 204 | for _, v := range s.Em { 205 | if !mp[v.Name] { 206 | mp[v.Name] = true 207 | p.Add(v.Generate()) 208 | } 209 | } 210 | p.Add("}") 211 | 212 | return p.Generates() 213 | } 214 | 215 | // \033[3%d;%dm -%d;%d-colors!\033[0m\n 216 | // GeneratesColor Get the result data on color.获取结果数据 带颜色 217 | func (s *GenStruct) GeneratesColor() []string { 218 | var p generate.PrintAtom 219 | if config.GetIsOutSQL() { 220 | p.Add("\033[32;1m /******sql******\033[0m") 221 | p.Add(s.SQLBuildStr) 222 | p.Add("\033[32;1m ******sql******/ \033[0m") 223 | } 224 | p.Add("\033[32;1m " + s.Notes + " \033[0m") 225 | p.Add("\033[34;1m type \033[0m", s.Name, "\033[34;1m struct \033[0m {") 226 | mp := make(map[string]bool, len(s.Em)) 227 | for _, v := range s.Em { 228 | if !mp[v.Name] { 229 | mp[v.Name] = true 230 | p.Add(" \t\t" + v.GenerateColor()) 231 | } 232 | } 233 | p.Add(" }") 234 | 235 | return p.Generates() 236 | } 237 | 238 | ////////////////////////////////////////////////////////////////////////////// 239 | // package 240 | ////////////////////////////////////////////////////////////////////////////// 241 | 242 | // SetPackage Defining package names.定义包名 243 | func (p *GenPackage) SetPackage(pname string) { 244 | p.Name = pname 245 | } 246 | 247 | // AddImport Add import by type.通过类型添加import 248 | func (p *GenPackage) AddImport(imp string) { 249 | if p.Imports == nil { 250 | p.Imports = make(map[string]string) 251 | } 252 | p.Imports[imp] = imp 253 | } 254 | 255 | // AddStruct Add a structure.添加一个结构体 256 | func (p *GenPackage) AddStruct(st GenStruct) { 257 | p.Structs = append(p.Structs, st) 258 | } 259 | 260 | // Generate Get the result data.获取结果数据 261 | func (p *GenPackage) Generate() string { 262 | p.genimport() // auto add import .补充 import 263 | 264 | var pa generate.PrintAtom 265 | pa.Add("package", p.Name) 266 | // add import 267 | if p.Imports != nil { 268 | pa.Add("import (") 269 | for _, v := range p.Imports { 270 | pa.Add(v) 271 | } 272 | pa.Add(")") 273 | } 274 | // -----------end 275 | // add struct 276 | for _, v := range p.Structs { 277 | for _, v1 := range v.Generates() { 278 | pa.Add(v1) 279 | } 280 | 281 | if config.GetIsTableName() { // add table name func 282 | for _, v1 := range v.GenerateTableName() { 283 | pa.Add(v1) 284 | } 285 | } 286 | 287 | if config.GetIsColumnName() { 288 | for _, v2 := range v.GenerateColumnName() { // add column list 289 | pa.Add(v2) 290 | } 291 | } 292 | } 293 | // -----------end 294 | 295 | // add func 296 | for _, v := range p.FuncStrList { 297 | pa.Add(v) 298 | } 299 | // -----------end 300 | 301 | // output.输出 302 | strOut := "" 303 | for _, v := range pa.Generates() { 304 | strOut += v + "\n" 305 | } 306 | 307 | return strOut 308 | } 309 | 310 | // AddFuncStr add func coding string.添加函数串 311 | func (p *GenPackage) AddFuncStr(src string) { 312 | p.FuncStrList = append(p.FuncStrList, src) 313 | } 314 | 315 | // compensate and import .获取结果数据 316 | func (p *GenPackage) genimport() { 317 | for _, v := range p.Structs { 318 | for _, v1 := range v.Em { 319 | if v2, ok := cnf.EImportsHead[v1.Type]; ok { 320 | if len(v2) > 0 { 321 | p.AddImport(v2) 322 | } 323 | } 324 | } 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /data/view/genstruct/def.go: -------------------------------------------------------------------------------- 1 | package genstruct 2 | 3 | // GenElement element of sturct.元素类 4 | type GenElement struct { 5 | Name string // Name.元素名 6 | ColumnName string // table name.表名 7 | Type string // Type.类型标记 8 | Notes string // Notes.注释 9 | Tags map[string][]string // tages.标记 10 | } 11 | 12 | // GenStruct struct of IStruct .结构体 13 | type GenStruct struct { 14 | SQLBuildStr string // Create SQL statements.创建sql语句 15 | TableName string // table_name.表名 16 | Name string // name.名字 17 | Notes string // notes.注释 18 | Em []GenElement // em.元素组合 19 | } 20 | 21 | // GenPackage package of IPackage.包体 22 | type GenPackage struct { 23 | Name string // name.名字 24 | Imports map[string]string // Inclusion term.元素组合 25 | Structs []GenStruct // struct list .结构体组合 26 | FuncStrList []string // func of template on string. 函数的最终定义 27 | } 28 | -------------------------------------------------------------------------------- /data/view/gtools/gtools.go: -------------------------------------------------------------------------------- 1 | package gtools 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | 7 | "github.com/xxjwxc/public/mylog" 8 | 9 | "github.com/xxjwxc/gormt/data/dlg" 10 | "github.com/xxjwxc/gormt/data/view/model" 11 | 12 | "github.com/xxjwxc/gormt/data/config" 13 | 14 | "github.com/xxjwxc/gormt/data/view/model/genmssql" 15 | "github.com/xxjwxc/gormt/data/view/model/genmysql" 16 | "github.com/xxjwxc/gormt/data/view/model/gensqlite" 17 | "github.com/xxjwxc/public/tools" 18 | ) 19 | 20 | // Execute exe the cmd 21 | func Execute() { 22 | if config.GetIsGUI() { 23 | dlg.WinMain() 24 | } else { 25 | showCmd() 26 | } 27 | } 28 | 29 | func showCmd() { 30 | // var tt oauth_db.UserInfoTbl 31 | // tt.Nickname = "ticket_001" 32 | // orm.Where("nickname = ?", "ticket_001").Find(&tt) 33 | // fmt.Println(tt) 34 | var modeldb model.IModel 35 | switch config.GetDbInfo().Type { 36 | case 0: // mysql 37 | modeldb = genmysql.GetModel() 38 | case 1: // sqllite 39 | modeldb = gensqlite.GetModel() 40 | case 2: // 41 | modeldb = genmssql.GetModel() 42 | } 43 | if modeldb == nil { 44 | mylog.Error(fmt.Errorf("modeldb not fund : please check db_info.type (0:mysql , 1:sqlite , 2:mssql) ")) 45 | return 46 | } 47 | 48 | pkg := modeldb.GenModel() 49 | // gencnf.GenOutPut(&pkg) 50 | // just for test 51 | // out, _ := json.Marshal(pkg) 52 | // tools.WriteFile("test.txt", []string{string(out)}, true) 53 | 54 | list, _ := model.Generate(pkg) 55 | 56 | for _, v := range list { 57 | path := config.GetOutDir() + "/" + v.FileName 58 | tools.WriteFile(path, []string{v.FileCtx}, true) 59 | 60 | mylog.Info("fix structure fields for memory alignment") 61 | cmd, _ := exec.Command("fieldalignment", "-fix", path).Output() 62 | mylog.Info(string(cmd)) 63 | 64 | mylog.Info("formatting differs from goimport's:") 65 | cmd, _ = exec.Command("goimports", "-l", "-w", path).Output() 66 | mylog.Info(string(cmd)) 67 | 68 | mylog.Info("formatting differs from gofmt's:") 69 | cmd, _ = exec.Command("gofmt", "-l", "-w", path).Output() 70 | mylog.Info(string(cmd)) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /data/view/gtools/gtools_test.go: -------------------------------------------------------------------------------- 1 | package gtools 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/xxjwxc/gormt/data/view/model" 9 | ) 10 | 11 | // TestTools 12 | func TestTools(t *testing.T) { 13 | str := `{"DbName":"oauth_db","PackageName":"model","TabList":[{"Name":"user_account_tbl","Notes":"用户账号","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"account","Notes":"","Type":"varchar(64)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"password","Notes":"","Type":"varchar(64)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"account_type","Notes":"帐号类型:0手机号,1邮件","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"authbucket_oauth2_client表的id","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"user_info_tbl_id","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":"user_info_id"}],"IsNull":false,"ForeignKeyList":[{"TableName":"user_info_tbl","ColumnName":"id"}]},{"Name":"reg_time","Notes":"","Type":"datetime","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"reg_ip","Notes":"","Type":"varchar(15)","Index":[{"Key":3,"KeyName":"user_info_id"}],"IsNull":true,"ForeignKeyList":null},{"Name":"bundle_id","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"describ","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"user_info_tbl","Notes":"用户信息","SQLBuildStr":"","Em":[{"Name":"","Notes":"","Type":"gorm.Model","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"nickname","Notes":"","Type":"varchar(32)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"headurl","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"oauth2_access_token","Notes":"token认证","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"access_token","Notes":"","Type":"varchar(255)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"token_type","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"key","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"username","Notes":"用户名","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expires","Notes":"过期时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"user","Notes":"","SQLBuildStr":"","Em":[{"Name":"userId","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"name","Notes":"","Type":"varchar(30)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"sex","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"job","Notes":"","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"organ","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"userId","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":""}],"IsNull":true,"ForeignKeyList":[{"TableName":"user","ColumnName":"sex"}]},{"Name":"type","Notes":"","Type":"int(11)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"score","Notes":"","Type":"int(11)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"sign_client_tbl","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_secret","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expire_time","Notes":"超时时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"strict_sign","Notes":"是否强制验签:0:用户自定义,1:强制","Type":"int(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"strict_verify","Notes":"是否强制验证码:0:用户自定义,1:强制","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"token过期时间","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"user_paybill_order","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"paybill_id","Notes":"二次账单id","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_id_mysql","Notes":"MySql中的订单Id","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_item_id_mysql","Notes":"MySql中的订单ItemId","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_id_mssql","Notes":"MsSql中的订单Id","Type":"bigint(20)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"oauth2_client_tbl","Notes":"client key 信息","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_secret","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expire_time","Notes":"超时时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"strict_sign","Notes":"是否强制验签:0:用户自定义,1:强制","Type":"int(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"strict_verify","Notes":"是否强制验证码:0:用户自定义,1:强制","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"token过期时间","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"aaa","Notes":"","Type":"json","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"oauth2_refresh_token","Notes":"刷新token","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"refresh_token","Notes":"","Type":"varchar(255)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"token_type","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"username","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expires","Notes":"","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]}]}` 14 | var pkg model.DBInfo 15 | json.Unmarshal([]byte(str), &pkg) 16 | // out, _ := json.Marshal(pkg) 17 | // tools.WriteFile("test.txt", []string{string(out)}, true) 18 | 19 | list, _ := model.Generate(pkg) 20 | fmt.Println(list) 21 | } 22 | -------------------------------------------------------------------------------- /data/view/model/common.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "regexp" 7 | "strings" 8 | "text/template" 9 | 10 | "github.com/xxjwxc/gormt/data/config" 11 | "github.com/xxjwxc/gormt/data/view/cnf" 12 | "github.com/xxjwxc/gormt/data/view/genfunc" 13 | "github.com/xxjwxc/public/mybigcamel" 14 | "github.com/xxjwxc/public/tools" 15 | ) 16 | 17 | // getCamelName Big Hump or Capital Letter.大驼峰或者首字母大写 18 | func getCamelName(name string) string { 19 | // if !config.GetSingularTable() { // If the table name plural is globally disabled.如果全局禁用表名复数 20 | // return mybigcamel.Marshal(strings.TrimSuffix(name, "s")) 21 | // } 22 | 23 | return mybigcamel.Marshal(strings.ToLower(name)) 24 | } 25 | 26 | // titleCase title case.首字母大写 27 | func titleCase(name string) string { 28 | vv := []rune(name) 29 | if len(vv) > 0 { 30 | if bool(vv[0] >= 'a' && vv[0] <= 'z') { // title case.首字母大写 31 | vv[0] -= 32 32 | } 33 | } 34 | 35 | return string(vv) 36 | } 37 | 38 | // CapLowercase 小写.且兼容 golint 驼峰命名规则 39 | func CapLowercase(name string) string { // IDAPIID == > idAPIID 40 | list := strings.Split(mybigcamel.UnMarshal(name), "_") 41 | if len(list) == 0 { 42 | return "" 43 | } 44 | 45 | re := list[0] + name[len(list[0]):] 46 | 47 | return FilterKeywords(re) 48 | } 49 | 50 | // GetTablePrefixName 获取带表前缀名字的tablename 51 | func GetTablePrefixName(name string) string { // 52 | tablePrefix := config.GetTablePrefix() 53 | //如果设置了表前缀 54 | if tablePrefix == "" || strings.HasPrefix(tablePrefix, "-") { 55 | return name 56 | } 57 | 58 | return tablePrefix + name 59 | } 60 | 61 | func FilterKeywords(src string) string { 62 | if tools.IsKeywords(src) { 63 | return "_" + src 64 | } 65 | return src 66 | } 67 | 68 | // getTypeName Type acquisition filtering.类型获取过滤 69 | func getTypeName(name string, isNull bool) string { 70 | // 优先匹配自定义类型 71 | selfDefineTypeMqlDicMap := config.GetSelfTypeDefine() 72 | if v, ok := selfDefineTypeMqlDicMap[name]; ok { 73 | return fixNullToPorint(v, isNull) 74 | } 75 | 76 | // Fuzzy Regular Matching.模糊正则匹配自定义类型 77 | for selfKey, selfVal := range selfDefineTypeMqlDicMap { 78 | if ok, _ := regexp.MatchString(selfKey, name); ok { 79 | return fixNullToPorint(selfVal, isNull) 80 | } 81 | } 82 | 83 | // Precise matching first.先精确匹配 84 | if v, ok := cnf.TypeMysqlDicMp[name]; ok { 85 | return fixNullToPorint(v, isNull) 86 | } 87 | 88 | // Fuzzy Regular Matching.模糊正则匹配 89 | for _, l := range cnf.TypeMysqlMatchList { 90 | if ok, _ := regexp.MatchString(l.Key, name); ok { 91 | return fixNullToPorint(l.Value, isNull) 92 | } 93 | } 94 | 95 | panic(fmt.Sprintf("type (%v) not match in any way.maybe need to add on (https://github.com/xxjwxc/gormt/blob/master/data/view/cnf/def.go)", name)) 96 | } 97 | 98 | // 过滤null point 类型 99 | func fixNullToPorint(name string, isNull bool) string { 100 | if isNull && config.GetIsNullToPoint() { 101 | if strings.HasPrefix(name, "uint") { 102 | return "*" + name 103 | } 104 | if strings.HasPrefix(name, "int") { 105 | return "*" + name 106 | } 107 | if strings.HasPrefix(name, "float") { 108 | return "*" + name 109 | } 110 | if strings.HasPrefix(name, "date") { 111 | return "*" + name 112 | } 113 | if strings.HasPrefix(name, "time") { 114 | return "*" + name 115 | } 116 | if strings.HasPrefix(name, "bool") { 117 | return "*" + name 118 | } 119 | if strings.HasPrefix(name, "string") { 120 | return "*" + name 121 | } 122 | } 123 | if isNull && config.GetIsNullToSqlNull() { 124 | 125 | if strings.HasPrefix(name, "uint") { 126 | return "sql.NullInt64" 127 | } 128 | if strings.HasPrefix(name, "int") { 129 | return "sql.NullInt32" 130 | } 131 | if strings.HasPrefix(name, "float") { 132 | return "sql.NullFloat64" 133 | } 134 | if strings.HasPrefix(name, "date") { 135 | return "sql.NullTime" 136 | } 137 | if strings.HasPrefix(name, "time") { 138 | return "sql.NullTime" 139 | } 140 | if strings.HasPrefix(name, "bool") { 141 | return "sql.NullBool" 142 | } 143 | if strings.HasPrefix(name, "string") { 144 | return "sql.NullString" 145 | } 146 | } 147 | 148 | return name 149 | } 150 | 151 | func getUninStr(left, middle, right string) string { 152 | re := left 153 | if len(right) > 0 { 154 | re = left + middle + right 155 | } 156 | return re 157 | } 158 | 159 | func getGormModelElement() []EmInfo { 160 | var result []EmInfo 161 | result = append(result, EmInfo{ 162 | IsMulti: false, 163 | Notes: "Primary key", 164 | Type: "int64", // Type.类型标记 165 | ColName: "id", 166 | ColNameEx: "id", 167 | ColStructName: "ID", 168 | }) 169 | 170 | result = append(result, EmInfo{ 171 | IsMulti: false, 172 | Notes: "created time", 173 | Type: "time.Time", // Type.类型标记 174 | ColName: "created_at", 175 | ColNameEx: "created_at", 176 | ColStructName: "CreatedAt", 177 | }) 178 | 179 | result = append(result, EmInfo{ 180 | IsMulti: false, 181 | Notes: "updated at", 182 | Type: "time.Time", // Type.类型标记 183 | ColName: "updated_at", 184 | ColNameEx: "updated_at", 185 | ColStructName: "UpdatedAt", 186 | }) 187 | 188 | result = append(result, EmInfo{ 189 | IsMulti: false, 190 | Notes: "deleted time", 191 | Type: "gorm.DeletedAt", // Type.类型标记 192 | ColName: "deleted_at", 193 | ColNameEx: "deleted_at", 194 | ColStructName: "DeletedAt", 195 | }) 196 | return result 197 | } 198 | 199 | func buildFList(list *[]FList, key ColumnsKey, keyName, tp, colName string) { 200 | for i := 0; i < len(*list); i++ { 201 | if (*list)[i].KeyName == keyName { 202 | (*list)[i].Kem = append((*list)[i].Kem, FEm{ 203 | Type: tp, 204 | ColName: colName, 205 | ColStructName: getCamelName(colName), 206 | }) 207 | return 208 | } 209 | } 210 | // 没有 添加一个 211 | *list = append(*list, FList{ 212 | Key: key, 213 | KeyName: keyName, 214 | Kem: []FEm{{ 215 | Type: tp, 216 | ColName: colName, 217 | ColStructName: getCamelName(colName), 218 | }}, 219 | }) 220 | } 221 | 222 | // GenPreloadList 生成list 223 | func GenPreloadList(list []PreloadInfo, multi bool) string { 224 | if len(list) > 0 { 225 | tmpl, err := template.New("gen_preload").Parse(genfunc.GetGenPreloadTemp(multi)) 226 | if err != nil { 227 | panic(err) 228 | } 229 | var buf bytes.Buffer 230 | tmpl.Execute(&buf, list) 231 | 232 | return buf.String() 233 | } 234 | 235 | return "" 236 | } 237 | 238 | // GenFListIndex 生成list status(1:获取函数名,2:获取参数列表,3:获取sql case,4:值列表) 239 | func GenFListIndex(info FList, status int) string { 240 | switch status { 241 | case 1: // 1:获取函数名 242 | { 243 | return widthFunctionName(info) 244 | } 245 | case 2: // 2:获取参数列表 246 | { 247 | var strs []string 248 | for _, v := range info.Kem { 249 | strs = append(strs, fmt.Sprintf("%v %v ", CapLowercase(v.ColStructName), v.Type)) 250 | } 251 | return strings.Join(strs, ",") 252 | } 253 | case 3: // 3:获取sql case, 254 | { 255 | var strs []string 256 | for _, v := range info.Kem { 257 | strs = append(strs, fmt.Sprintf("`%v` = ?", v.ColName)) //wxw 2021.2.26 16:53 258 | } 259 | return strings.Join(strs, " AND ") 260 | } 261 | case 4: // 4:值列表 262 | { 263 | var strs []string 264 | for _, v := range info.Kem { 265 | strs = append(strs, CapLowercase(v.ColStructName)) 266 | } 267 | return strings.Join(strs, " , ") 268 | } 269 | } 270 | 271 | return "" 272 | } 273 | 274 | func widthFunctionName(info FList) string { 275 | switch info.Key { 276 | // case ColumnsKeyDefault: 277 | case ColumnsKeyPrimary: // primary key.主键 278 | return "FetchByPrimaryKey" 279 | case ColumnsKeyUnique: // unique key.唯一索引 280 | return "FetchUniqueBy" + getCamelName(info.KeyName) 281 | case ColumnsKeyIndex: // index key.复合索引 282 | return "FetchIndexBy" + getCamelName(info.KeyName) 283 | case ColumnsKeyUniqueIndex: // unique index key.唯一复合索引 284 | return "FetchUniqueIndexBy" + getCamelName(info.KeyName) 285 | } 286 | 287 | return "" 288 | } 289 | 290 | func fixNotes(str string) string { // 注释 291 | return strings.Replace(str, "\n", "\n//", -1) 292 | } 293 | -------------------------------------------------------------------------------- /data/view/model/def.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | const ( 4 | // _tagGorm = "gorm" 5 | // _tagJSON = "json" 6 | ) 7 | 8 | // ColumnsKey Columns type elem. 类型枚举 9 | type ColumnsKey int 10 | 11 | const ( 12 | // ColumnsKeyDefault default 13 | ColumnsKeyDefault = iota 14 | // ColumnsKeyPrimary primary key.主键 15 | ColumnsKeyPrimary // 主键 16 | // ColumnsKeyUnique unique key.唯一索引 17 | ColumnsKeyUnique // unix 唯一索引 18 | // ColumnsKeyIndex index key.复合索引 19 | ColumnsKeyIndex // 可重复 index 索引 20 | // ColumnsKeyUniqueIndex unique index key.唯一复合索引 21 | ColumnsKeyUniqueIndex // 唯一复合索引 22 | ) 23 | 24 | // DBInfo database default info 25 | type DBInfo struct { 26 | DbName string // database name 27 | PackageName string // package name 28 | TabList []TabInfo // table list .表列表 29 | } 30 | 31 | // TabInfo database table default attribute 32 | type TabInfo struct { 33 | BaseInfo 34 | SQLBuildStr string // Create SQL statements.创建sql语句 35 | Em []ColumnsInfo // Columns list .表列表组合 36 | } 37 | 38 | // ColumnsInfo Columns list .表列信息 39 | type ColumnsInfo struct { 40 | BaseInfo 41 | IsNull bool // null if db is set null 42 | Extra string // Extra (AUTO_INCREMENT 自增加) 43 | Type string // Type.类型标记 44 | Gormt string // 默认值 45 | Index []KList // index list.index列表 46 | ForeignKeyList []ForeignKey // Foreign key list . 表的外键信息 47 | } 48 | 49 | // ForeignKey Foreign key of db info . 表的外键信息 50 | type ForeignKey struct { 51 | TableName string // Affected tables . 该索引受影响的表 52 | ColumnName string // Which column of the affected table.该索引受影响的表的哪一列 53 | } 54 | 55 | // KList database index /unique_index list.数据库index /unique_index 列表 56 | type KList struct { 57 | Key ColumnsKey // non_unique of (show keys from [table]) 58 | Multi bool // Multiple .是否多个(复合组建) 59 | KeyName string // key_name of (show keys from [table]) 60 | KeyType string // Key_type of (show keys from [Index_type]) 61 | } 62 | 63 | // BaseInfo base common attribute. 基础属性 64 | type BaseInfo struct { 65 | Name string // table name.表名 66 | Notes string // table comment . 表注释 67 | } 68 | 69 | // GenOutInfo generate file list. 生成的文件列表 70 | type GenOutInfo struct { 71 | FileName string // output file name .输出文件名 72 | FileCtx string // output file context. 输出文件内容 73 | } 74 | 75 | // def func sturct 76 | 77 | // PreloadInfo 预加载列表 78 | type PreloadInfo struct { 79 | IsMulti bool 80 | Notes string // 注释 81 | ForeignkeyStructName string // 外键类目 82 | ForeignkeyTableName string // 外键表名 83 | ForeignkeyCol string // 外键列表 84 | ColName string // 表名 85 | ColStructName string // 表结构体 86 | } 87 | 88 | // EmInfo func 表结构定义 89 | 90 | // FEm ... 91 | type FEm struct { 92 | Type string // 类型 93 | ColName string // 列名 94 | ColStructName string // 列结构体 95 | } 96 | 97 | // FList index of list 98 | type FList struct { 99 | Key ColumnsKey // non_unique of (show keys from [table]) 100 | KeyName string // key_name of (show keys from [table]) 101 | Kem []FEm 102 | } 103 | 104 | // EmInfo element of func info 105 | type EmInfo struct { 106 | IsMulti bool 107 | Notes string // 注释 108 | Type string // 类型 109 | ColName string // 列名 110 | ColNameEx string // `列名` 111 | ColStructName string // 列结构体 112 | } 113 | 114 | type funDef struct { 115 | StructName string 116 | TableName string 117 | PreloadList []PreloadInfo // 外键列表,(生成关联数据) 118 | Em []EmInfo // index 列表 119 | Primary []FList // primary unique 120 | Index []FList // index 121 | IsOutPage bool // 是否开启分页 122 | } 123 | 124 | // 125 | -------------------------------------------------------------------------------- /data/view/model/def_ifs.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | // IModel Implement the interface to acquire database information and initialize it.实现接口获取数据库信息获取并初始化 4 | type IModel interface { 5 | GenModel() DBInfo 6 | GetDbName() string 7 | GetPkgName() string // Getting package names through config outdir configuration.通过config outdir 配置获取包名 8 | GetTableNames() string // Getting tableNames by config. 获取设置的表名 9 | } 10 | -------------------------------------------------------------------------------- /data/view/model/gencnf/gencnf.go: -------------------------------------------------------------------------------- 1 | package gencnf 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path" 7 | "strings" 8 | 9 | "gopkg.in/yaml.v3" 10 | 11 | "github.com/xxjwxc/gormt/data/config" 12 | "github.com/xxjwxc/gormt/data/view/model" 13 | "github.com/xxjwxc/public/mylog" 14 | "github.com/xxjwxc/public/tools" 15 | ) 16 | 17 | // GetCnfModel get model interface. 获取model接口 18 | func GetCnfModel() model.IModel { 19 | //now just support mysql 20 | return &CnfModel 21 | } 22 | 23 | // GenOutPut 输出 24 | func GenOutPut(info *model.DBInfo) { 25 | path := path.Join(config.GetOutDir(), info.DbName+".yml") 26 | out, _ := yaml.Marshal(info) 27 | 28 | flag := os.O_CREATE | os.O_WRONLY | os.O_TRUNC 29 | f, err := os.OpenFile(path, flag, 0666) 30 | if err != nil { 31 | mylog.Error(err) 32 | return 33 | } 34 | defer f.Close() 35 | f.Write(out) 36 | } 37 | 38 | // CnfModel yaml model from IModel 39 | var CnfModel cnfModel 40 | 41 | type cnfModel struct { 42 | } 43 | 44 | // GenModel get model.DBInfo info.获取数据库相关属性 45 | func (m *cnfModel) GenModel() model.DBInfo { 46 | var dbInfo model.DBInfo 47 | // getPackageInfo(orm, &dbInfo) 48 | // 添加逻辑 49 | dbInfo.PackageName = m.GetPkgName() 50 | dbInfo.DbName = m.GetDbName() 51 | return dbInfo 52 | } 53 | 54 | // GetTableNames get table name.获取指定的表名 55 | func (m *cnfModel) GetTableNames() string { 56 | return config.GetTableNames() 57 | } 58 | 59 | // GetDbName get database name.获取数据库名字 60 | func (m *cnfModel) GetDbName() string { 61 | dir := config.GetDbInfo().Host 62 | dir = strings.Replace(dir, "\\", "/", -1) 63 | if len(dir) > 0 { 64 | if dir[len(dir)-1] == '/' { 65 | dir = dir[:(len(dir) - 1)] 66 | } 67 | } 68 | var dbName string 69 | list := strings.Split(dir, "/") 70 | if len(list) > 0 { 71 | dbName = list[len(list)-1] 72 | } 73 | list = strings.Split(dbName, ".") 74 | if len(list) > 0 { 75 | dbName = list[0] 76 | } 77 | 78 | if len(dbName) == 0 || dbName == "." { 79 | panic(fmt.Sprintf("%v : db host config err.must file dir", dbName)) 80 | } 81 | 82 | return dbName 83 | } 84 | 85 | // GetPkgName package names through config outdir configuration.通过config outdir 配置获取包名 86 | func (m *cnfModel) GetPkgName() string { 87 | dir := config.GetOutDir() 88 | dir = strings.Replace(dir, "\\", "/", -1) 89 | if len(dir) > 0 { 90 | if dir[len(dir)-1] == '/' { 91 | dir = dir[:(len(dir) - 1)] 92 | } 93 | } 94 | var pkgName string 95 | list := strings.Split(dir, "/") 96 | if len(list) > 0 { 97 | pkgName = list[len(list)-1] 98 | } 99 | 100 | if len(pkgName) == 0 || pkgName == "." { 101 | curDir := tools.GetModelPath() 102 | curDir = strings.Replace(curDir, "\\", "/", -1) 103 | list = strings.Split(curDir, "/") 104 | if len(list) > 0 { 105 | pkgName = list[len(list)-1] 106 | } 107 | } 108 | 109 | return pkgName 110 | } 111 | -------------------------------------------------------------------------------- /data/view/model/genmssql/common.go: -------------------------------------------------------------------------------- 1 | package genmssql 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/xxjwxc/gormt/data/config" 7 | "github.com/xxjwxc/public/mylog" 8 | 9 | "github.com/xxjwxc/gormt/data/view/model" 10 | ) 11 | 12 | // filterModel filter.过滤 gorm.Model 13 | func filterModel(list *[]genColumns) bool { 14 | if config.GetDBTag() != "gorm" || !config.GetUserGormModel() { 15 | return false 16 | } 17 | 18 | var _temp []genColumns 19 | num := 0 20 | for _, v := range *list { 21 | if strings.EqualFold(v.Field, "id") || 22 | strings.EqualFold(v.Field, "created_at") || 23 | strings.EqualFold(v.Field, "updated_at") || 24 | strings.EqualFold(v.Field, "deleted_at") { 25 | num++ 26 | } else { 27 | _temp = append(_temp, v) 28 | } 29 | } 30 | 31 | if num >= 4 { 32 | *list = _temp 33 | return true 34 | } 35 | 36 | return false 37 | } 38 | 39 | // fixForeignKey fix foreign key.过滤外键 40 | func fixForeignKey(list []genForeignKey, columuName string, result *[]model.ForeignKey) { 41 | for _, v := range list { 42 | if strings.EqualFold(v.ColumnName, columuName) { // find it .找到了 43 | *result = append(*result, model.ForeignKey{ 44 | TableName: v.ReferencedTableName, 45 | ColumnName: v.ReferencedColumnName, 46 | }) 47 | } 48 | } 49 | } 50 | 51 | // GetModel get model interface. 获取model接口 52 | func GetModel() model.IModel { 53 | //now just support mysql 54 | return &MssqlModel 55 | } 56 | 57 | // FixNotes 分析元素表注释 58 | func FixNotes(em *model.ColumnsInfo, note string) { 59 | b0 := FixElementTag(em, note) // gorm 60 | b1 := FixForeignKeyTag(em, em.Notes) // 外键 61 | if !b0 && b1 { // 补偿 62 | FixElementTag(em, em.Notes) // gorm 63 | } 64 | } 65 | 66 | // FixElementTag 分析元素表注释 67 | func FixElementTag(em *model.ColumnsInfo, note string) bool { 68 | matches := noteRegex.FindStringSubmatch(note) 69 | if len(matches) < 2 { 70 | em.Notes = note 71 | return false 72 | } 73 | 74 | mylog.Infof("get one gorm tag:(%v) ==> (%v)", em.BaseInfo.Name, matches[1]) 75 | em.Notes = note[len(matches[0]):] 76 | em.Gormt = matches[1] 77 | return true 78 | } 79 | 80 | // FixForeignKeyTag 分析元素表注释(外键) 81 | func FixForeignKeyTag(em *model.ColumnsInfo, note string) bool { 82 | matches := foreignKeyRegex.FindStringSubmatch(note) // foreign key 外键 83 | if len(matches) < 2 { 84 | em.Notes = note 85 | return false 86 | } 87 | em.Notes = note[len(matches[0]):] 88 | 89 | // foreign key 外键 90 | tmp := strings.Split(matches[1], ".") 91 | if len(tmp) > 0 { 92 | mylog.Infof("get one foreign key:(%v) ==> (%v)", em.BaseInfo.Name, matches[1]) 93 | em.ForeignKeyList = append(em.ForeignKeyList, model.ForeignKey{ 94 | TableName: tmp[0], 95 | ColumnName: tmp[1], 96 | }) 97 | } 98 | 99 | return true 100 | } 101 | -------------------------------------------------------------------------------- /data/view/model/genmssql/def.go: -------------------------------------------------------------------------------- 1 | package genmssql 2 | 3 | import "regexp" 4 | 5 | // genColumns show full columns 6 | type genColumns struct { 7 | Field string `gorm:"column:Field"` 8 | Type string `gorm:"column:Type"` 9 | Key string `gorm:"column:Key"` 10 | Desc string `gorm:"column:Comment"` 11 | Null string `gorm:"column:Null"` 12 | Default *string `gorm:"column:Default"` 13 | } 14 | 15 | //select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE 16 | // where table_schema ='matrix' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'credit_card' ; 17 | // genForeignKey Foreign key of db info . 表的外键信息 18 | type genForeignKey struct { 19 | TableSchema string `gorm:"column:table_schema"` // Database of columns.列所在的数据库 20 | TableName string `gorm:"column:table_name"` // Data table of column.列所在的数据表 21 | ColumnName string `gorm:"column:column_name"` // Column names.列名 22 | ReferencedTableSchema string `gorm:"column:referenced_table_schema"` // The database where the index is located.该索引所在的数据库 23 | ReferencedTableName string `gorm:"column:referenced_table_name"` // Affected tables . 该索引受影响的表 24 | ReferencedColumnName string `gorm:"column:referenced_column_name"` // Which column of the affected table.该索引受影响的表的哪一列 25 | } 26 | 27 | ///////////////////////////////////////////////////////////////////////// 28 | 29 | // TableDescription 表及表注释 30 | type TableDescription struct { 31 | Name string `gorm:"column:name"` // 表名 32 | Value string `gorm:"column:value"` // 表注释 33 | } 34 | 35 | type ColumnKeys struct { 36 | ID int `gorm:"column:id"` 37 | Name string `gorm:"column:name"` // 列名 38 | Pk int `gorm:"column:pk"` // 是否主键 39 | Type string `gorm:"column:tp"` // 类型 40 | Length int `gorm:"column:len"` // 长度 41 | Isnull int `gorm:"column:isnull"` // 是否为空 42 | Desc string `gorm:"column:des"` // 列注释 43 | } 44 | 45 | var noteRegex = regexp.MustCompile(`^\[@gorm\s(\S+)+\]`) 46 | var foreignKeyRegex = regexp.MustCompile(`^\[@fk\s(\S+)+\]`) 47 | -------------------------------------------------------------------------------- /data/view/model/genmssql/genmssql.go: -------------------------------------------------------------------------------- 1 | package genmssql 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | "strings" 7 | 8 | "github.com/xxjwxc/gormt/data/config" 9 | "github.com/xxjwxc/gormt/data/view/model" 10 | "github.com/xxjwxc/public/mylog" 11 | "github.com/xxjwxc/public/tools" 12 | "gorm.io/driver/sqlserver" 13 | "gorm.io/gorm" 14 | ) 15 | 16 | // MssqlModel mysql model from IModel 17 | var MssqlModel mssqlModel 18 | 19 | type mssqlModel struct { 20 | } 21 | 22 | // GenModel get model.DBInfo info.获取数据库相关属性 23 | func (m *mssqlModel) GenModel() model.DBInfo { 24 | dsn := fmt.Sprintf("server=%v;database=%v;user id=%v;password=%v;port=%v;encrypt=disable", 25 | config.GetDbInfo().Host, config.GetDbInfo().Database, config.GetDbInfo().Username, config.GetDbInfo().Password, config.GetDbInfo().Port) 26 | db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{}) 27 | if err != nil { 28 | mylog.Error(err) 29 | return model.DBInfo{} 30 | } 31 | defer func() { 32 | sqldb, _ := db.DB() 33 | sqldb.Close() 34 | }() 35 | 36 | var dbInfo model.DBInfo 37 | m.getPackageInfo(db, &dbInfo) 38 | dbInfo.PackageName = m.GetPkgName() 39 | dbInfo.DbName = m.GetDbName() 40 | return dbInfo 41 | } 42 | 43 | // GetDbName get database name.获取数据库名字 44 | func (m *mssqlModel) GetDbName() string { 45 | return config.GetDbInfo().Database 46 | } 47 | 48 | // GetTableNames get table name.获取格式化后指定的表名 49 | func (m *mssqlModel) GetTableNames() string { 50 | return config.GetTableNames() 51 | } 52 | 53 | // GetOriginTableNames get table name.获取原始指定的表名 54 | func (m *mssqlModel) GetOriginTableNames() string { 55 | return config.GetOriginTableNames() 56 | } 57 | 58 | // GetPkgName package names through config outdir configuration.通过config outdir 配置获取包名 59 | func (m *mssqlModel) GetPkgName() string { 60 | dir := config.GetOutDir() 61 | dir = strings.Replace(dir, "\\", "/", -1) 62 | if len(dir) > 0 { 63 | if dir[len(dir)-1] == '/' { 64 | dir = dir[:(len(dir) - 1)] 65 | } 66 | } 67 | var pkgName string 68 | list := strings.Split(dir, "/") 69 | if len(list) > 0 { 70 | pkgName = list[len(list)-1] 71 | } 72 | 73 | if len(pkgName) == 0 || pkgName == "." { 74 | list = strings.Split(tools.GetModelPath(), "/") 75 | if len(list) > 0 { 76 | pkgName = list[len(list)-1] 77 | } 78 | } 79 | 80 | return pkgName 81 | } 82 | 83 | func (m *mssqlModel) getPackageInfo(orm *gorm.DB, info *model.DBInfo) { 84 | tabls := m.getTables(orm) // get table and notes 85 | // if m := config.GetTableList(); len(m) > 0 { 86 | // // 制定了表之后 87 | // newTabls := make(map[string]string) 88 | // for t := range m { 89 | // if notes, ok := tabls[t]; ok { 90 | // newTabls[t] = notes 91 | // } else { 92 | // fmt.Printf("table: %s not found in db\n", t) 93 | // } 94 | // } 95 | // tabls = newTabls 96 | // } 97 | for tabName, notes := range tabls { 98 | var tab model.TabInfo 99 | tab.Name = tabName 100 | tab.Notes = notes 101 | 102 | if config.GetIsOutSQL() { 103 | // TODO:获取创建sql语句 104 | // Get create SQL statements.获取创建sql语句 105 | // rows, err := orm.Raw("show create table " + assemblyTable(tabName)).Rows() 106 | // //defer rows.Close() 107 | // if err == nil { 108 | // if rows.Next() { 109 | // var table, CreateTable string 110 | // rows.Scan(&table, &CreateTable) 111 | // tab.SQLBuildStr = CreateTable 112 | // } 113 | // } 114 | // rows.Close() 115 | // ----------end 116 | } 117 | 118 | // build element.构造元素 119 | tab.Em = m.getTableElement(orm, tabName) 120 | // --------end 121 | 122 | info.TabList = append(info.TabList, tab) 123 | } 124 | // sort tables 125 | sort.Slice(info.TabList, func(i, j int) bool { 126 | return info.TabList[i].Name < info.TabList[j].Name 127 | }) 128 | } 129 | 130 | // getTableElement Get table columns and comments.获取表列及注释 131 | func (m *mssqlModel) getTableElement(orm *gorm.DB, tab string) (el []model.ColumnsInfo) { 132 | sql := fmt.Sprintf(`SELECT 133 | id = a.colorder, 134 | name = a.name, 135 | pk = case when exists(SELECT 1 FROM sysobjects where xtype='PK' and parent_obj=a.id and name in ( 136 | SELECT name FROM sysindexes WHERE indid in( SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid))) then 1 else 0 end, 137 | tp = b.name, 138 | len = COLUMNPROPERTY(a.id,a.name,'PRECISION'), 139 | isnull = a.isnullable, 140 | des = isnull(g.[value],'') 141 | FROM 142 | syscolumns a 143 | left join 144 | systypes b 145 | on 146 | a.xusertype=b.xusertype 147 | inner join 148 | sysobjects d 149 | on 150 | a.id=d.id and d.xtype='U' and d.name<>'dtproperties' 151 | left join 152 | sys.extended_properties g 153 | on 154 | a.id=G.major_id and a.colid=g.minor_id 155 | left join 156 | sys.extended_properties f 157 | on 158 | d.id=f.major_id and f.minor_id=0 159 | where 160 | d.name='%v' 161 | order by 162 | a.colorder`, tab) 163 | 164 | lenPk := 0 165 | // get keys 166 | var Keys []ColumnKeys 167 | orm.Raw(sql).Scan(&Keys) 168 | for i := 0; i < len(Keys); i++ { 169 | v := &Keys[i] 170 | if v.Pk == 1 { 171 | lenPk++ 172 | } 173 | if strings.EqualFold(v.Type, "varchar") { // 字符串 174 | v.Type = fmt.Sprintf("varchar(%v)", v.Length) 175 | } else if strings.EqualFold(v.Type, "int") { // int 176 | v.Type = fmt.Sprintf("int(%v)", v.Length) 177 | } 178 | } 179 | // ----------end 180 | 181 | // TODO:ForeignKey 182 | 183 | for _, v := range Keys { 184 | var tmp model.ColumnsInfo 185 | tmp.Name = v.Name 186 | tmp.Type = v.Type 187 | FixNotes(&tmp, v.Desc) // 分析表注释 188 | 189 | if v.Pk > 0 { // 主键,或者联合组件 190 | if lenPk <= 1 { // 主键 191 | tmp.Index = append(tmp.Index, model.KList{ 192 | Key: model.ColumnsKeyPrimary, 193 | Multi: false, 194 | KeyType: "primaryKey", 195 | }) 196 | } else { 197 | tmp.Index = append(tmp.Index, model.KList{ 198 | Key: model.ColumnsKeyPrimary, 199 | Multi: true, 200 | KeyType: "FULLTEXT", 201 | }) 202 | } 203 | } 204 | 205 | tmp.IsNull = (v.Isnull == 1) 206 | 207 | el = append(el, tmp) 208 | } 209 | return 210 | } 211 | 212 | // getTables Get columns and comments.获取表列及注释 213 | func (m *mssqlModel) getTables(orm *gorm.DB) map[string]string { 214 | tbDesc := make(map[string]string) 215 | 216 | // Get column names.获取列名 217 | if m.GetOriginTableNames() != "" { 218 | sarr := strings.Split(m.GetOriginTableNames(), ",") 219 | if len(sarr) != 0 { 220 | for _, val := range sarr { 221 | tbDesc[val] = "" 222 | } 223 | } 224 | } else { 225 | var list []TableDescription 226 | err := orm.Raw(`SELECT DISTINCT 227 | d.name, 228 | f.value 229 | FROM 230 | syscolumns a 231 | LEFT JOIN systypes b ON a.xusertype= b.xusertype 232 | INNER JOIN sysobjects d ON a.id= d.id 233 | AND d.xtype= 'U' 234 | AND d.name<> 'dtproperties' 235 | LEFT JOIN syscomments e ON a.cdefault= e.id 236 | LEFT JOIN sys.extended_properties g ON a.id= G.major_id 237 | AND a.colid= g.minor_id 238 | LEFT JOIN sys.extended_properties f ON d.id= f.major_id 239 | AND f.minor_id= 0 ;`).Scan(&list).Error 240 | if err != nil { 241 | if !config.GetIsGUI() { 242 | fmt.Println(err) 243 | } 244 | return tbDesc 245 | } 246 | 247 | for _, v := range list { 248 | tbDesc[v.Name] = v.Value 249 | } 250 | } 251 | 252 | return tbDesc 253 | } 254 | 255 | func assemblyTable(name string) string { 256 | return "`" + name + "`" 257 | } 258 | -------------------------------------------------------------------------------- /data/view/model/genmysql/common.go: -------------------------------------------------------------------------------- 1 | package genmysql 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/xxjwxc/gormt/data/config" 7 | "github.com/xxjwxc/public/mylog" 8 | 9 | "github.com/xxjwxc/gormt/data/view/model" 10 | ) 11 | 12 | // filterModel filter.过滤 gorm.Model 13 | func filterModel(list *[]genColumns) bool { 14 | if config.GetDBTag() != "gorm" || !config.GetUserGormModel() { 15 | return false 16 | } 17 | 18 | var _temp []genColumns 19 | num := 0 20 | for _, v := range *list { 21 | if strings.EqualFold(v.Field, "id") || 22 | strings.EqualFold(v.Field, "created_at") || 23 | strings.EqualFold(v.Field, "updated_at") || 24 | strings.EqualFold(v.Field, "deleted_at") { 25 | num++ 26 | } else { 27 | _temp = append(_temp, v) 28 | } 29 | } 30 | 31 | if num >= 4 { 32 | *list = _temp 33 | return true 34 | } 35 | 36 | return false 37 | } 38 | 39 | // fixForeignKey fix foreign key.过滤外键 40 | func fixForeignKey(list []genForeignKey, columuName string, result *[]model.ForeignKey) { 41 | for _, v := range list { 42 | if strings.EqualFold(v.ColumnName, columuName) { // find it .找到了 43 | *result = append(*result, model.ForeignKey{ 44 | TableName: v.ReferencedTableName, 45 | ColumnName: v.ReferencedColumnName, 46 | }) 47 | } 48 | } 49 | } 50 | 51 | // GetModel get model interface. 获取model接口 52 | func GetModel() model.IModel { 53 | //now just support mysql 54 | return &MySQLModel 55 | } 56 | 57 | // FixNotes 分析元素表注释 58 | func FixNotes(em *model.ColumnsInfo, note string) { 59 | b0 := FixElementTag(em, note) // gorm 60 | b1 := FixForeignKeyTag(em, em.Notes) // 外键 61 | if !b0 && b1 { // 补偿 62 | FixElementTag(em, em.Notes) // gorm 63 | } 64 | } 65 | 66 | // FixElementTag 分析元素表注释 67 | func FixElementTag(em *model.ColumnsInfo, note string) bool { 68 | matches := noteRegex.FindStringSubmatch(note) 69 | if len(matches) < 2 { 70 | em.Notes = note 71 | return false 72 | } 73 | 74 | mylog.Infof("get one gorm tag:(%v) ==> (%v)", em.BaseInfo.Name, matches[1]) 75 | em.Notes = note[len(matches[0]):] 76 | em.Gormt = matches[1] 77 | return true 78 | } 79 | 80 | // FixForeignKeyTag 分析元素表注释(外键) 81 | func FixForeignKeyTag(em *model.ColumnsInfo, note string) bool { 82 | matches := foreignKeyRegex.FindStringSubmatch(note) // foreign key 外键 83 | if len(matches) < 2 { 84 | em.Notes = note 85 | return false 86 | } 87 | em.Notes = note[len(matches[0]):] 88 | 89 | // foreign key 外键 90 | tmp := strings.Split(matches[1], ".") 91 | if len(tmp) > 0 { 92 | mylog.Infof("get one foreign key:(%v) ==> (%v)", em.BaseInfo.Name, matches[1]) 93 | em.ForeignKeyList = append(em.ForeignKeyList, model.ForeignKey{ 94 | TableName: tmp[0], 95 | ColumnName: tmp[1], 96 | }) 97 | } 98 | 99 | return true 100 | } 101 | -------------------------------------------------------------------------------- /data/view/model/genmysql/def.go: -------------------------------------------------------------------------------- 1 | package genmysql 2 | 3 | import "regexp" 4 | 5 | type keys struct { 6 | NonUnique int `gorm:"column:Non_unique"` 7 | KeyName string `gorm:"column:Key_name"` 8 | ColumnName string `gorm:"column:Column_name"` 9 | IndexType string `gorm:"column:Index_type"` 10 | } 11 | 12 | // genColumns show full columns 13 | type genColumns struct { 14 | Field string `gorm:"column:Field"` 15 | Type string `gorm:"column:Type"` 16 | Key string `gorm:"column:Key"` 17 | Desc string `gorm:"column:Comment"` 18 | Null string `gorm:"column:Null"` 19 | Extra string `gorm:"Extra"` 20 | Default *string `gorm:"column:Default"` 21 | } 22 | 23 | //select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE 24 | // where table_schema ='matrix' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'credit_card' ; 25 | // genForeignKey Foreign key of db info . 表的外键信息 26 | type genForeignKey struct { 27 | TableSchema string `gorm:"column:table_schema"` // Database of columns.列所在的数据库 28 | TableName string `gorm:"column:table_name"` // Data table of column.列所在的数据表 29 | ColumnName string `gorm:"column:column_name"` // Column names.列名 30 | ReferencedTableSchema string `gorm:"column:referenced_table_schema"` // The database where the index is located.该索引所在的数据库 31 | ReferencedTableName string `gorm:"column:referenced_table_name"` // Affected tables . 该索引受影响的表 32 | ReferencedColumnName string `gorm:"column:referenced_column_name"` // Which column of the affected table.该索引受影响的表的哪一列 33 | } 34 | 35 | var noteRegex = regexp.MustCompile(`^\[@gorm\s(\S+)+\]`) 36 | var foreignKeyRegex = regexp.MustCompile(`^\[@fk\s(\S+)+\]`) 37 | -------------------------------------------------------------------------------- /data/view/model/genmysql/genmysql.go: -------------------------------------------------------------------------------- 1 | package genmysql 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | "sort" 7 | "strings" 8 | 9 | "github.com/xxjwxc/gormt/data/config" 10 | "github.com/xxjwxc/gormt/data/view/model" 11 | "github.com/xxjwxc/public/mysqldb" 12 | "github.com/xxjwxc/public/tools" 13 | ) 14 | 15 | // MySQLModel mysql model from IModel 16 | var MySQLModel mysqlModel 17 | 18 | type mysqlModel struct { 19 | } 20 | 21 | // GenModel get model.DBInfo info.获取数据库相关属性 22 | func (m *mysqlModel) GenModel() model.DBInfo { 23 | orm := mysqldb.OnInitDBOrm(config.GetMysqlConStr(), true) 24 | defer orm.OnDestoryDB() 25 | 26 | var dbInfo model.DBInfo 27 | m.getPackageInfo(orm, &dbInfo) 28 | dbInfo.PackageName = m.GetPkgName() 29 | dbInfo.DbName = m.GetDbName() 30 | return dbInfo 31 | } 32 | 33 | // GetDbName get database name.获取数据库名字 34 | func (m *mysqlModel) GetDbName() string { 35 | return config.GetDbInfo().Database 36 | } 37 | 38 | // GetTableNames get table name.获取格式化后指定的表名 39 | func (m *mysqlModel) GetTableNames() string { 40 | return config.GetTableNames() 41 | } 42 | 43 | // GetOriginTableNames get table name.获取原始指定的表名 44 | func (m *mysqlModel) GetOriginTableNames() string { 45 | return config.GetOriginTableNames() 46 | } 47 | 48 | // GetPkgName package names through config outdir configuration.通过config outdir 配置获取包名 49 | func (m *mysqlModel) GetPkgName() string { 50 | dir := config.GetOutDir() 51 | dir = strings.Replace(dir, "\\", "/", -1) 52 | if len(dir) > 0 { 53 | if dir[len(dir)-1] == '/' { 54 | dir = dir[:(len(dir) - 1)] 55 | } 56 | } 57 | var pkgName string 58 | list := strings.Split(dir, "/") 59 | if len(list) > 0 { 60 | pkgName = list[len(list)-1] 61 | } 62 | 63 | if len(pkgName) == 0 || pkgName == "." { 64 | list = strings.Split(tools.GetModelPath(), "/") 65 | if len(list) > 0 { 66 | pkgName = list[len(list)-1] 67 | } 68 | } 69 | 70 | return pkgName 71 | } 72 | 73 | func (m *mysqlModel) getPackageInfo(orm *mysqldb.MySqlDB, info *model.DBInfo) { 74 | tabls := m.getTables(orm) // get table and notes 75 | // if m := config.GetTableList(); len(m) > 0 { 76 | // // 制定了表之后 77 | // newTabls := make(map[string]string) 78 | // for t := range m { 79 | // if notes, ok := tabls[t]; ok { 80 | // newTabls[t] = notes 81 | // } else { 82 | // fmt.Printf("table: %s not found in db\n", t) 83 | // } 84 | // } 85 | // tabls = newTabls 86 | // } 87 | for tabName, notes := range tabls { 88 | var tab model.TabInfo 89 | tab.Name = tabName 90 | tab.Notes = notes 91 | 92 | if config.GetIsOutSQL() { 93 | // Get create SQL statements.获取创建sql语句 94 | rows, err := orm.Raw("show create table " + assemblyTable(tabName)).Rows() 95 | //defer rows.Close() 96 | if err == nil { 97 | if rows.Next() { 98 | var table, CreateTable string 99 | rows.Scan(&table, &CreateTable) 100 | tab.SQLBuildStr = CreateTable 101 | } 102 | } 103 | rows.Close() 104 | // ----------end 105 | } 106 | 107 | // build element.构造元素 108 | tab.Em = m.getTableElement(orm, tabName) 109 | // --------end 110 | 111 | info.TabList = append(info.TabList, tab) 112 | } 113 | // sort tables 114 | sort.Slice(info.TabList, func(i, j int) bool { 115 | return info.TabList[i].Name < info.TabList[j].Name 116 | }) 117 | } 118 | 119 | // getTableElement Get table columns and comments.获取表列及注释 120 | func (m *mysqlModel) getTableElement(orm *mysqldb.MySqlDB, tab string) (el []model.ColumnsInfo) { 121 | keyNameCount := make(map[string]int) 122 | KeyColumnMp := make(map[string][]keys) 123 | // get keys 124 | var Keys []keys 125 | orm.Raw("show keys from " + assemblyTable(tab)).Scan(&Keys) 126 | for _, v := range Keys { 127 | keyNameCount[v.KeyName]++ 128 | KeyColumnMp[v.ColumnName] = append(KeyColumnMp[v.ColumnName], v) 129 | } 130 | // ----------end 131 | 132 | var list []genColumns 133 | // Get table annotations.获取表注释 134 | orm.Raw("show FULL COLUMNS from " + assemblyTable(tab)).Scan(&list) 135 | // filter gorm.Model.过滤 gorm.Model 136 | if filterModel(&list) { 137 | el = append(el, model.ColumnsInfo{ 138 | Type: "gorm.Model", 139 | }) 140 | } 141 | // -----------------end 142 | 143 | // ForeignKey 144 | var foreignKeyList []genForeignKey 145 | if config.GetIsForeignKey() { 146 | sql := fmt.Sprintf(`select table_schema as table_schema,table_name as table_name,column_name as column_name,referenced_table_schema as referenced_table_schema,referenced_table_name as referenced_table_name,referenced_column_name as referenced_column_name 147 | from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where table_schema = '%v' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = '%v'`, m.GetDbName(), tab) 148 | orm.Raw(sql).Scan(&foreignKeyList) 149 | } 150 | // ------------------end 151 | 152 | for _, v := range list { 153 | var tmp model.ColumnsInfo 154 | tmp.Name = v.Field 155 | tmp.Type = v.Type 156 | tmp.Extra = v.Extra 157 | FixNotes(&tmp, v.Desc) // 分析表注释 158 | 159 | if v.Default != nil { 160 | if *v.Default == "" { 161 | tmp.Gormt = "default:''" 162 | } else { 163 | tmp.Gormt = fmt.Sprintf("default:%s", *v.Default) 164 | } 165 | } 166 | 167 | // keys 168 | if keylist, ok := KeyColumnMp[v.Field]; ok { // maybe have index or key 169 | for _, v := range keylist { 170 | if v.NonUnique == 0 { // primary or unique 171 | if strings.EqualFold(v.KeyName, "PRIMARY") { // PRI Set primary key.设置主键 172 | tmp.Index = append(tmp.Index, model.KList{ 173 | Key: model.ColumnsKeyPrimary, 174 | Multi: (keyNameCount[v.KeyName] > 1), 175 | KeyType: v.IndexType, 176 | }) 177 | } else { // unique 178 | if keyNameCount[v.KeyName] > 1 { 179 | tmp.Index = append(tmp.Index, model.KList{ 180 | Key: model.ColumnsKeyUniqueIndex, 181 | Multi: (keyNameCount[v.KeyName] > 1), 182 | KeyName: v.KeyName, 183 | KeyType: v.IndexType, 184 | }) 185 | } else { // unique index key.唯一复合索引 186 | tmp.Index = append(tmp.Index, model.KList{ 187 | Key: model.ColumnsKeyUnique, 188 | Multi: (keyNameCount[v.KeyName] > 1), 189 | KeyName: v.KeyName, 190 | KeyType: v.IndexType, 191 | }) 192 | } 193 | } 194 | } else { // mut 195 | tmp.Index = append(tmp.Index, model.KList{ 196 | Key: model.ColumnsKeyIndex, 197 | Multi: true, 198 | KeyName: v.KeyName, 199 | KeyType: v.IndexType, 200 | }) 201 | } 202 | } 203 | } 204 | 205 | tmp.IsNull = strings.EqualFold(v.Null, "YES") 206 | 207 | // ForeignKey 208 | fixForeignKey(foreignKeyList, tmp.Name, &tmp.ForeignKeyList) 209 | // -----------------end 210 | el = append(el, tmp) 211 | } 212 | return 213 | } 214 | 215 | // getTables Get columns and comments.获取表列及注释 216 | func (m *mysqlModel) getTables(orm *mysqldb.MySqlDB) map[string]string { 217 | tbDesc := make(map[string]string) 218 | 219 | // Get column names.获取列名 220 | var tables []string 221 | 222 | if m.GetOriginTableNames() != "" { 223 | sarr := strings.Split(m.GetOriginTableNames(), ",") 224 | if len(sarr) != 0 { 225 | for _, val := range sarr { 226 | tbDesc[val] = "" 227 | } 228 | } 229 | } else { 230 | rows, err := orm.Raw("show tables").Rows() 231 | if err != nil { 232 | if !config.GetIsGUI() { 233 | fmt.Println(err) 234 | } 235 | return tbDesc 236 | } 237 | 238 | for rows.Next() { 239 | var table string 240 | rows.Scan(&table) 241 | tables = append(tables, table) 242 | tbDesc[table] = "" 243 | } 244 | rows.Close() 245 | } 246 | 247 | // Get table annotations.获取表注释 248 | var err error 249 | var rows1 *sql.Rows 250 | if m.GetTableNames() != "" { 251 | rows1, err = orm.Raw("SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.TABLES WHERE table_schema= '" + m.GetDbName() + "'and TABLE_NAME IN(" + m.GetTableNames() + ")").Rows() 252 | fmt.Println("getTables:" + m.GetTableNames()) 253 | fmt.Println("SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.TABLES WHERE table_schema= '" + m.GetDbName() + "'and TABLE_NAME IN(" + m.GetTableNames() + ")") 254 | } else { 255 | rows1, err = orm.Raw("SELECT TABLE_NAME,TABLE_COMMENT FROM information_schema.TABLES WHERE table_schema= '" + m.GetDbName() + "'").Rows() 256 | } 257 | 258 | if err != nil { 259 | if !config.GetIsGUI() { 260 | fmt.Println(err) 261 | } 262 | return tbDesc 263 | } 264 | 265 | for rows1.Next() { 266 | var table, desc string 267 | rows1.Scan(&table, &desc) 268 | tbDesc[table] = desc 269 | } 270 | rows1.Close() 271 | 272 | return tbDesc 273 | } 274 | 275 | func assemblyTable(name string) string { 276 | return "`" + name + "`" 277 | } 278 | -------------------------------------------------------------------------------- /data/view/model/gensqlite/common.go: -------------------------------------------------------------------------------- 1 | package gensqlite 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/xxjwxc/gormt/data/config" 7 | 8 | "github.com/xxjwxc/gormt/data/view/model" 9 | ) 10 | 11 | // filterModel filter.过滤 gorm.Model 12 | func filterModel(list *[]genColumns) bool { 13 | if config.GetDBTag() != "gorm" || !config.GetUserGormModel() { 14 | return false 15 | } 16 | 17 | var _temp []genColumns 18 | num := 0 19 | for _, v := range *list { 20 | if strings.EqualFold(v.Name, "id") || 21 | strings.EqualFold(v.Name, "created_at") || 22 | strings.EqualFold(v.Name, "updated_at") || 23 | strings.EqualFold(v.Name, "deleted_at") { 24 | num++ 25 | } else { 26 | _temp = append(_temp, v) 27 | } 28 | } 29 | 30 | if num >= 4 { 31 | *list = _temp 32 | return true 33 | } 34 | 35 | return false 36 | } 37 | 38 | // fixForeignKey fix foreign key.过滤外键 39 | func fixForeignKey(list []genForeignKey, columuName string, result *[]model.ForeignKey) { 40 | for _, v := range list { 41 | if strings.EqualFold(v.ColumnName, columuName) { // find it .找到了 42 | *result = append(*result, model.ForeignKey{ 43 | TableName: v.ReferencedTableName, 44 | ColumnName: v.ReferencedColumnName, 45 | }) 46 | } 47 | } 48 | } 49 | 50 | // GetModel get model interface. 获取model接口 51 | func GetModel() model.IModel { 52 | //now just support mysql 53 | return &SQLiteModel 54 | } 55 | 56 | // FixNotes 分析元素表注释 57 | func FixNotes(em *model.ColumnsInfo, note string) { 58 | b0 := FixElementTag(em, note) // gorm 59 | b1 := FixForeignKeyTag(em, em.Notes) // 外键 60 | if !b0 && b1 { // 补偿 61 | FixElementTag(em, em.Notes) // gorm 62 | } 63 | } 64 | 65 | // FixElementTag 分析元素表注释 66 | func FixElementTag(em *model.ColumnsInfo, note string) bool { 67 | matches := noteRegex.FindStringSubmatch(note) 68 | if len(matches) < 2 { 69 | em.Notes = note 70 | return false 71 | } 72 | em.Notes = note[len(matches[0]):] 73 | em.Gormt = matches[1] 74 | return true 75 | } 76 | 77 | // FixForeignKeyTag 分析元素表注释(外键) 78 | func FixForeignKeyTag(em *model.ColumnsInfo, note string) bool { 79 | matches := foreignKeyRegex.FindStringSubmatch(note) // foreign key 外键 80 | if len(matches) < 2 { 81 | em.Notes = note 82 | return false 83 | } 84 | em.Notes = note[len(matches[0]):] 85 | 86 | // foreign key 外键 87 | tmp := strings.Split(matches[1], ".") 88 | if len(tmp) > 0 { 89 | em.ForeignKeyList = append(em.ForeignKeyList, model.ForeignKey{ 90 | TableName: tmp[0], 91 | ColumnName: tmp[1], 92 | }) 93 | } 94 | 95 | return true 96 | } 97 | -------------------------------------------------------------------------------- /data/view/model/gensqlite/def.go: -------------------------------------------------------------------------------- 1 | package gensqlite 2 | 3 | import "regexp" 4 | 5 | type keys struct { 6 | NonUnique int `gorm:"column:Non_unique"` 7 | KeyName string `gorm:"column:Key_name"` 8 | ColumnName string `gorm:"column:Column_name"` 9 | } 10 | 11 | // genColumns show full columns 12 | type genColumns struct { 13 | Name string `gorm:"column:name"` 14 | Type string `gorm:"column:type"` 15 | Pk int `gorm:"column:pk"` 16 | NotNull int `gorm:"column:notnull"` 17 | } 18 | 19 | //select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE 20 | // where table_schema ='matrix' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'credit_card' ; 21 | // genForeignKey Foreign key of db info . 表的外键信息 22 | type genForeignKey struct { 23 | TableSchema string `gorm:"column:table_schema"` // Database of columns.列所在的数据库 24 | TableName string `gorm:"column:table_name"` // Data table of column.列所在的数据表 25 | ColumnName string `gorm:"column:column_name"` // Column names.列名 26 | ReferencedTableSchema string `gorm:"column:referenced_table_schema"` // The database where the index is located.该索引所在的数据库 27 | ReferencedTableName string `gorm:"column:referenced_table_name"` // Affected tables . 该索引受影响的表 28 | ReferencedColumnName string `gorm:"column:referenced_column_name"` // Which column of the affected table.该索引受影响的表的哪一列 29 | } 30 | 31 | var noteRegex = regexp.MustCompile(`^\[@gorm\s(\S+)+\]`) 32 | var foreignKeyRegex = regexp.MustCompile(`^\[@fk\s(\S+)+\]`) 33 | -------------------------------------------------------------------------------- /data/view/model/gensqlite/gensqlite.go: -------------------------------------------------------------------------------- 1 | package gensqlite 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | "strings" 7 | 8 | "github.com/xxjwxc/public/mylog" 9 | 10 | "github.com/xxjwxc/gormt/data/config" 11 | "github.com/xxjwxc/gormt/data/view/model" 12 | "github.com/xxjwxc/public/tools" 13 | "gorm.io/driver/sqlite" 14 | "gorm.io/gorm" 15 | ) 16 | 17 | // SQLiteModel mysql model from IModel 18 | var SQLiteModel sqliteModel 19 | 20 | type sqliteModel struct { 21 | } 22 | 23 | // GenModel get model.DBInfo info.获取数据库相关属性 24 | func (m *sqliteModel) GenModel() model.DBInfo { 25 | db, err := gorm.Open(sqlite.Open(config.GetDbInfo().Host), &gorm.Config{}) 26 | if err != nil { 27 | mylog.Error(err) 28 | return model.DBInfo{} 29 | } 30 | defer func() { 31 | sqldb, _ := db.DB() 32 | sqldb.Close() 33 | }() 34 | 35 | var dbInfo model.DBInfo 36 | m.getPackageInfo(db, &dbInfo) 37 | dbInfo.PackageName = m.GetPkgName() 38 | dbInfo.DbName = m.GetDbName() 39 | return dbInfo 40 | } 41 | 42 | // GetDbName get database name.获取数据库名字 43 | func (m *sqliteModel) GetDbName() string { 44 | dir := config.GetDbInfo().Host 45 | dir = strings.Replace(dir, "\\", "/", -1) 46 | if len(dir) > 0 { 47 | if dir[len(dir)-1] == '/' { 48 | dir = dir[:(len(dir) - 1)] 49 | } 50 | } 51 | var dbName string 52 | list := strings.Split(dir, "/") 53 | if len(list) > 0 { 54 | dbName = list[len(list)-1] 55 | } 56 | list = strings.Split(dbName, ".") 57 | if len(list) > 0 { 58 | dbName = list[0] 59 | } 60 | 61 | if len(dbName) == 0 || dbName == "." { 62 | panic(fmt.Sprintf("%v : db host config err.must file dir", dbName)) 63 | } 64 | 65 | return dbName 66 | } 67 | 68 | // GetTableNames get table name.获取指定的表名 69 | func (m *sqliteModel) GetTableNames() string { 70 | return config.GetTableNames() 71 | } 72 | 73 | // GetPkgName package names through config outdir configuration.通过config outdir 配置获取包名 74 | func (m *sqliteModel) GetPkgName() string { 75 | dir := config.GetOutDir() 76 | dir = strings.Replace(dir, "\\", "/", -1) 77 | if len(dir) > 0 { 78 | if dir[len(dir)-1] == '/' { 79 | dir = dir[:(len(dir) - 1)] 80 | } 81 | } 82 | var pkgName string 83 | list := strings.Split(dir, "/") 84 | if len(list) > 0 { 85 | pkgName = list[len(list)-1] 86 | } 87 | 88 | if len(pkgName) == 0 || pkgName == "." { 89 | list = strings.Split(tools.GetModelPath(), "/") 90 | if len(list) > 0 { 91 | pkgName = list[len(list)-1] 92 | } 93 | } 94 | 95 | return pkgName 96 | } 97 | 98 | func (m *sqliteModel) getPackageInfo(orm *gorm.DB, info *model.DBInfo) { 99 | tabls := m.getTables(orm) // get table and notes 100 | for tabName, notes := range tabls { 101 | var tab model.TabInfo 102 | tab.Name = tabName 103 | tab.Notes = notes 104 | 105 | if config.GetIsOutSQL() { 106 | // Get create SQL statements.获取创建sql语句 107 | rows, err := orm.Raw("SELECT tbl_name,sql FROM sqlite_master WHERE type='table' AND name = " + assemblyTable(tabName)).Rows() 108 | //defer rows.Close() 109 | if err == nil { 110 | if rows.Next() { 111 | var table, CreateTable string 112 | rows.Scan(&table, &CreateTable) 113 | tab.SQLBuildStr = CreateTable 114 | } 115 | } 116 | rows.Close() 117 | // ----------end 118 | } 119 | 120 | // build element.构造元素 121 | tab.Em = m.getTableElement(orm, tabName) 122 | // --------end 123 | 124 | info.TabList = append(info.TabList, tab) 125 | } 126 | // sort tables 127 | sort.Slice(info.TabList, func(i, j int) bool { 128 | return info.TabList[i].Name < info.TabList[j].Name 129 | }) 130 | } 131 | 132 | // getTableElement Get table columns and comments.获取表列及注释 133 | func (m *sqliteModel) getTableElement(orm *gorm.DB, tab string) (el []model.ColumnsInfo) { 134 | var list []genColumns 135 | // Get table annotations.获取表注释 136 | orm.Raw(fmt.Sprintf("PRAGMA table_info(%v)", assemblyTable(tab))).Scan(&list) 137 | // filter gorm.Model.过滤 gorm.Model 138 | if filterModel(&list) { 139 | el = append(el, model.ColumnsInfo{ 140 | Type: "gorm.Model", 141 | }) 142 | } 143 | // -----------------end 144 | 145 | // ForeignKey 146 | var foreignKeyList []genForeignKey 147 | if config.GetIsForeignKey() { 148 | } 149 | // ------------------end 150 | 151 | for _, v := range list { 152 | var tmp model.ColumnsInfo 153 | tmp.Name = v.Name 154 | tmp.Type = v.Type 155 | FixNotes(&tmp, "") 156 | if v.Pk == 1 { // 主键 157 | tmp.Index = append(tmp.Index, model.KList{ 158 | Key: model.ColumnsKeyPrimary, 159 | Multi: false, 160 | }) 161 | } 162 | 163 | tmp.IsNull = (v.NotNull != 1) 164 | 165 | // ForeignKey 166 | fixForeignKey(foreignKeyList, tmp.Name, &tmp.ForeignKeyList) 167 | // -----------------end 168 | el = append(el, tmp) 169 | } 170 | return 171 | } 172 | 173 | // getTables Get columns and comments.获取表列及注释 174 | func (m *sqliteModel) getTables(orm *gorm.DB) map[string]string { 175 | tbDesc := make(map[string]string) 176 | 177 | // Get column names.获取列名 178 | var tables []string 179 | 180 | rows, err := orm.Raw("SELECT name FROM sqlite_master WHERE type='table'").Rows() 181 | if err != nil { 182 | if !config.GetIsGUI() { 183 | fmt.Println(err) 184 | } 185 | return tbDesc 186 | } 187 | 188 | for rows.Next() { 189 | var table string 190 | rows.Scan(&table) 191 | if !strings.EqualFold(table, "sqlite_sequence") { // 剔除系统默认 192 | tables = append(tables, table) 193 | tbDesc[table] = "" 194 | } 195 | } 196 | rows.Close() 197 | 198 | // TODO.获取表注释 199 | 200 | return tbDesc 201 | } 202 | 203 | func assemblyTable(name string) string { 204 | return "'" + name + "'" 205 | } 206 | -------------------------------------------------------------------------------- /data/view/model/model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "strings" 7 | "text/template" 8 | 9 | "github.com/xxjwxc/gormt/data/view/cnf" 10 | 11 | "github.com/xxjwxc/public/mybigcamel" 12 | 13 | "github.com/xxjwxc/gormt/data/config" 14 | "github.com/xxjwxc/gormt/data/view/genfunc" 15 | "github.com/xxjwxc/gormt/data/view/genstruct" 16 | ) 17 | 18 | type _Model struct { 19 | info DBInfo 20 | pkg *genstruct.GenPackage 21 | } 22 | 23 | // Generate build code string.生成代码 24 | func Generate(info DBInfo) (out []GenOutInfo, m _Model) { 25 | m = _Model{ 26 | info: info, 27 | } 28 | 29 | // struct 30 | if config.GetIsOutFileByTableName() { 31 | outByTable := m.GenerateByTableName() 32 | out = append(out, outByTable...) 33 | } else { 34 | var stt GenOutInfo 35 | stt.FileCtx = m.generate() 36 | stt.FileName = info.DbName + ".go" 37 | 38 | if name := config.GetOutFileName(); len(name) > 0 { 39 | stt.FileName = name + ".go" 40 | } 41 | out = append(out, stt) 42 | } 43 | 44 | // ------end 45 | 46 | // gen function 47 | if config.GetIsOutFunc() { 48 | out = append(out, m.generateFunc()...) 49 | } 50 | // -------------- end 51 | return 52 | } 53 | 54 | // getTableNameWithPrefix get table name with prefix 55 | func getTableNameWithPrefix(tableName string) string { 56 | tablePrefix := config.GetTablePrefix() 57 | if tablePrefix == "" { 58 | return tableName 59 | } 60 | 61 | if strings.HasPrefix(tablePrefix, "-") { 62 | trimPrefix := strings.TrimPrefix(tablePrefix, "-") 63 | tableName = strings.TrimPrefix(tableName, trimPrefix) 64 | } else { 65 | tableName = tablePrefix + tableName 66 | } 67 | 68 | return tableName 69 | } 70 | 71 | // GetPackage gen struct on table 72 | func (m *_Model) GetPackage() genstruct.GenPackage { 73 | if m.pkg == nil { 74 | var pkg genstruct.GenPackage 75 | pkg.SetPackage(m.info.PackageName) //package name 76 | 77 | for _, tab := range m.info.TabList { 78 | var sct genstruct.GenStruct 79 | 80 | sct.SetTableName(tab.Name) 81 | 82 | tab.Name = getTableNameWithPrefix(tab.Name) 83 | fmt.Println(tab.Name) 84 | sct.SetStructName(getCamelName(tab.Name)) // Big hump.大驼峰 85 | sct.SetNotes(tab.Notes) 86 | sct.AddElement(m.genTableElement(tab.Em)...) // build element.构造元素 87 | sct.SetCreatTableStr(tab.SQLBuildStr) 88 | pkg.AddStruct(sct) 89 | } 90 | m.pkg = &pkg 91 | } 92 | 93 | return *m.pkg 94 | } 95 | 96 | // GetPackageByTableName Generate multiple model files based on the table name. 根据表名生成多个model文件 97 | func (m *_Model) GenerateByTableName() (out []GenOutInfo) { 98 | if m.pkg == nil { 99 | for _, tab := range m.info.TabList { 100 | var pkg genstruct.GenPackage 101 | pkg.SetPackage(m.info.PackageName) //package name 102 | var sct genstruct.GenStruct 103 | sct.SetTableName(tab.Name) 104 | tab.Name = getTableNameWithPrefix(tab.Name) 105 | sct.SetStructName(getCamelName(tab.Name)) // Big hump.大驼峰 106 | sct.SetNotes(tab.Notes) 107 | sct.AddElement(m.genTableElement(tab.Em)...) // build element.构造元素 108 | sct.SetCreatTableStr(tab.SQLBuildStr) 109 | pkg.AddStruct(sct) 110 | var stt GenOutInfo 111 | stt.FileCtx = pkg.Generate() 112 | stt.FileName = tab.Name + ".go" 113 | out = append(out, stt) 114 | } 115 | } 116 | return 117 | } 118 | 119 | func (m *_Model) generate() string { 120 | m.pkg = nil 121 | m.GetPackage() 122 | return m.pkg.Generate() 123 | } 124 | 125 | // genTableElement Get table columns and comments.获取表列及注释 126 | func (m *_Model) genTableElement(cols []ColumnsInfo) (el []genstruct.GenElement) { 127 | _tagGorm := config.GetDBTag() 128 | _tagJSON := config.GetURLTag() 129 | 130 | for _, v := range cols { 131 | var tmp genstruct.GenElement 132 | var isPK bool 133 | if strings.EqualFold(v.Type, "gorm.Model") { // gorm model 134 | tmp.SetType(v.Type) // 135 | } else { 136 | tmp.SetName(getCamelName(v.Name)) 137 | tmp.SetNotes(v.Notes) 138 | tmp.SetType(getTypeName(v.Type, v.IsNull)) 139 | // 是否输出gorm标签 140 | if len(_tagGorm) > 0 { 141 | // not simple output. 默认只输出gorm主键和字段标签 142 | if !config.GetSimple() { 143 | if strings.EqualFold(v.Extra, "auto_increment") { 144 | tmp.AddTag(_tagGorm, "autoIncrement:true") 145 | } 146 | for _, v1 := range v.Index { 147 | switch v1.Key { 148 | // case ColumnsKeyDefault: 149 | case ColumnsKeyPrimary: // primary key.主键 150 | tmp.AddTag(_tagGorm, "primaryKey") 151 | isPK = true 152 | case ColumnsKeyUnique: // unique key.唯一索引 153 | tmp.AddTag(_tagGorm, "unique") 154 | case ColumnsKeyIndex: // index key.复合索引 155 | uninStr := getUninStr("index", ":", v1.KeyName) 156 | // 兼容 gorm 本身 sort 标签 157 | if v1.KeyName == "sort" { 158 | uninStr = "index" 159 | } 160 | if v1.KeyType == "FULLTEXT" { 161 | uninStr += ",class:FULLTEXT" 162 | } 163 | tmp.AddTag(_tagGorm, uninStr) 164 | case ColumnsKeyUniqueIndex: // unique index key.唯一复合索引 165 | tmp.AddTag(_tagGorm, getUninStr("uniqueIndex", ":", v1.KeyName)) 166 | } 167 | } 168 | } else { 169 | for _, v1 := range v.Index { 170 | switch v1.Key { 171 | // case ColumnsKeyDefault: 172 | case ColumnsKeyPrimary: // primary key.主键 173 | tmp.AddTag(_tagGorm, "primaryKey") 174 | isPK = true 175 | } 176 | } 177 | } 178 | } 179 | } 180 | 181 | if len(v.Name) > 0 { 182 | // 是否输出gorm标签 183 | if len(_tagGorm) > 0 { 184 | // not simple output 185 | if !config.GetSimple() { 186 | tmp.AddTag(_tagGorm, "column:"+v.Name) 187 | tmp.AddTag(_tagGorm, "type:"+v.Type) 188 | if !v.IsNull { 189 | tmp.AddTag(_tagGorm, "not null") 190 | } else if v.IsNull && !config.GetIsNullToPoint() { 191 | // 当该字段默认值为null,并且结构不用指针类型时,添加default:null的tag 192 | tmp.AddTag(_tagGorm, "default:null") 193 | } 194 | // default tag 195 | if len(v.Gormt) > 0 { 196 | tmp.AddTag(_tagGorm, v.Gormt) 197 | } 198 | if len(v.Notes) > 0 { 199 | tmp.AddTag(_tagGorm, fmt.Sprintf("comment:'%v'", v.Notes)) 200 | } 201 | } else { 202 | tmp.AddTag(_tagGorm, "column:"+v.Name) 203 | } 204 | } 205 | 206 | // json tag 207 | if config.GetIsWEBTag() { 208 | if isPK && config.GetIsWebTagPkHidden() { 209 | tmp.AddTag(_tagJSON, "-") 210 | } else { 211 | if config.GetWebTagType() == 0 { 212 | tmp.AddTag(_tagJSON, mybigcamel.UnSmallMarshal(mybigcamel.Marshal(v.Name))) 213 | } else { 214 | tmp.AddTag(_tagJSON, mybigcamel.UnMarshal(v.Name)) 215 | } 216 | } 217 | } 218 | 219 | } 220 | 221 | tmp.ColumnName = v.Name // 列名 222 | el = append(el, tmp) 223 | 224 | // ForeignKey 225 | if config.GetIsForeignKey() && len(v.ForeignKeyList) > 0 { 226 | fklist := m.genForeignKey(v) 227 | el = append(el, fklist...) 228 | } 229 | // -----------end 230 | } 231 | 232 | return 233 | } 234 | 235 | // genForeignKey Get information about foreign key of table column.获取表列外键相关信息 236 | func (m *_Model) genForeignKey(col ColumnsInfo) (fklist []genstruct.GenElement) { 237 | _tagGorm := config.GetDBTag() 238 | _tagJSON := config.GetURLTag() 239 | 240 | for _, v := range col.ForeignKeyList { 241 | isMulti, isFind, notes := m.getColumnsKeyMulti(v.TableName, v.ColumnName) 242 | if isFind { 243 | var tmp genstruct.GenElement 244 | tmp.SetNotes(notes) 245 | if isMulti { 246 | tmp.SetName(getCamelName(v.TableName) + "List") 247 | tmp.SetType("[]" + getCamelName(v.TableName)) 248 | } else { 249 | tmp.SetName(getCamelName(v.TableName)) 250 | tmp.SetType(getCamelName(v.TableName)) 251 | } 252 | 253 | tmp.AddTag(_tagGorm, "joinForeignKey:"+col.Name) // association_foreignkey 254 | tmp.AddTag(_tagGorm, "foreignKey:"+v.ColumnName) 255 | tmp.AddTag(_tagGorm, "references:"+getCamelName(col.Name)) 256 | 257 | // json tag 258 | if config.GetIsWEBTag() { 259 | if config.GetWebTagType() == 0 { 260 | tmp.AddTag(_tagJSON, mybigcamel.UnSmallMarshal(mybigcamel.Marshal(v.TableName))+"List") 261 | } else { 262 | tmp.AddTag(_tagJSON, mybigcamel.UnMarshal(v.TableName)+"_list") 263 | } 264 | } 265 | 266 | fklist = append(fklist, tmp) 267 | } 268 | } 269 | 270 | return 271 | } 272 | 273 | func (m *_Model) getColumnsKeyMulti(tableName, col string) (isMulti bool, isFind bool, notes string) { 274 | var haveGomod bool 275 | for _, v := range m.info.TabList { 276 | if strings.EqualFold(v.Name, tableName) { 277 | for _, v1 := range v.Em { 278 | if strings.EqualFold(v1.Name, col) { 279 | for _, v2 := range v1.Index { 280 | switch v2.Key { 281 | case ColumnsKeyPrimary, ColumnsKeyUnique, ColumnsKeyUniqueIndex: // primary key unique key . 主键,唯一索引 282 | { 283 | if !v2.Multi { // 唯一索引 284 | return false, true, v.Notes 285 | } 286 | } 287 | // case ColumnsKeyIndex: // index key. 复合索引 288 | // { 289 | // isMulti = true 290 | // } 291 | } 292 | } 293 | return true, true, v.Notes 294 | } else if strings.EqualFold(v1.Type, "gorm.Model") { 295 | haveGomod = true 296 | notes = v.Notes 297 | } 298 | } 299 | break 300 | } 301 | } 302 | 303 | // default gorm.Model 304 | if haveGomod { 305 | if strings.EqualFold(col, "id") { 306 | return false, true, notes 307 | } 308 | 309 | if strings.EqualFold(col, "created_at") || 310 | strings.EqualFold(col, "updated_at") || 311 | strings.EqualFold(col, "deleted_at") { 312 | return true, true, notes 313 | } 314 | } 315 | 316 | return false, false, "" 317 | // -----------------end 318 | } 319 | 320 | // ///////////////////////// func 321 | func (m *_Model) generateFunc() (genOut []GenOutInfo) { 322 | // getn base 323 | tmpl, err := template.New("gen_base").Funcs(template.FuncMap{"GetVV": func() string { return "`%v`" }}).Parse(genfunc.GetGenBaseTemp()) 324 | if err != nil { 325 | panic(err) 326 | } 327 | var buf bytes.Buffer 328 | tmpl.Execute(&buf, m.info) 329 | genOut = append(genOut, GenOutInfo{ 330 | FileName: "gen.base.go", 331 | FileCtx: buf.String(), 332 | }) 333 | //tools.WriteFile(outDir+"gen_router.go", []string{buf.String()}, true) 334 | // -------end------ 335 | 336 | // gen page 分页查询的基础 337 | if config.GetIsOutPage() { 338 | genPage, err := template.New("gen_page").Parse(genfunc.GetGenPageTemp()) 339 | if err != nil { 340 | panic(err) 341 | } 342 | 343 | var bufPage bytes.Buffer 344 | genPage.Execute(&bufPage, m.info) 345 | genOut = append(genOut, GenOutInfo{ 346 | FileName: "gen.page.go", 347 | FileCtx: bufPage.String(), 348 | }) 349 | } 350 | // -------end------ 351 | 352 | for _, tab := range m.info.TabList { 353 | var pkg genstruct.GenPackage 354 | pkg.SetPackage(m.info.PackageName) //package name 355 | pkg.AddImport(`"fmt"`) 356 | pkg.AddImport(`"context"`) // 添加import信息 357 | pkg.AddImport(cnf.EImportsHead["gorm.Model"]) 358 | 359 | // wxw 2021.2.26 17:17 360 | var data funDef 361 | data.TableName = tab.Name 362 | data.IsOutPage = config.GetIsOutPage() // 添加分页开关 363 | tab.Name = getTableNameWithPrefix(tab.Name) 364 | 365 | data.StructName = getCamelName(tab.Name) 366 | 367 | var primary, unique, uniqueIndex, index []FList 368 | for _, el := range tab.Em { 369 | if strings.EqualFold(el.Type, "gorm.Model") { 370 | data.Em = append(data.Em, getGormModelElement()...) 371 | pkg.AddImport(`"time"`) 372 | buildFList(&primary, ColumnsKeyPrimary, "", "int64", "id") 373 | } else { 374 | typeName := getTypeName(el.Type, el.IsNull) 375 | isMulti := (len(el.Index) == 0) 376 | isUniquePrimary := false 377 | for _, v1 := range el.Index { 378 | if v1.Multi { 379 | isMulti = v1.Multi 380 | } 381 | 382 | switch v1.Key { 383 | // case ColumnsKeyDefault: 384 | case ColumnsKeyPrimary: // primary key.主键 385 | isUniquePrimary = !v1.Multi 386 | buildFList(&primary, ColumnsKeyPrimary, v1.KeyName, typeName, el.Name) 387 | case ColumnsKeyUnique: // unique key.唯一索引 388 | buildFList(&unique, ColumnsKeyUnique, v1.KeyName, typeName, el.Name) 389 | case ColumnsKeyIndex: // index key.复合索引 390 | buildFList(&index, ColumnsKeyIndex, v1.KeyName, typeName, el.Name) 391 | case ColumnsKeyUniqueIndex: // unique index key.唯一复合索引 392 | buildFList(&uniqueIndex, ColumnsKeyUniqueIndex, v1.KeyName, typeName, el.Name) 393 | } 394 | } 395 | 396 | if isMulti && isUniquePrimary { // 主键唯一 397 | isMulti = false 398 | } 399 | 400 | data.Em = append(data.Em, EmInfo{ 401 | IsMulti: isMulti, 402 | Notes: fixNotes(el.Notes), 403 | Type: typeName, // Type.类型标记 404 | ColName: el.Name, 405 | ColNameEx: fmt.Sprintf("`%v`", el.Name), 406 | ColStructName: getCamelName(el.Name), 407 | }) 408 | if v2, ok := cnf.EImportsHead[typeName]; ok { 409 | if len(v2) > 0 { 410 | pkg.AddImport(v2) 411 | } 412 | } 413 | } 414 | 415 | // 外键列表 416 | for _, v := range el.ForeignKeyList { 417 | isMulti, isFind, notes := m.getColumnsKeyMulti(v.TableName, v.ColumnName) 418 | if isFind { 419 | var info PreloadInfo 420 | info.IsMulti = isMulti 421 | info.Notes = fixNotes(notes) 422 | info.ForeignkeyTableName = v.TableName 423 | info.ForeignkeyCol = v.ColumnName 424 | info.ForeignkeyStructName = getCamelName(v.TableName) 425 | info.ColName = el.Name 426 | info.ColStructName = getCamelName(el.Name) 427 | data.PreloadList = append(data.PreloadList, info) 428 | } 429 | } 430 | // ---------end-- 431 | } 432 | 433 | data.Primary = append(data.Primary, primary...) 434 | data.Primary = append(data.Primary, unique...) 435 | data.Primary = append(data.Primary, uniqueIndex...) 436 | data.Index = append(data.Index, index...) 437 | tmpl, err := template.New("gen_logic"). 438 | Funcs(template.FuncMap{"GenPreloadList": GenPreloadList, "GenFListIndex": GenFListIndex, "CapLowercase": CapLowercase, "GetTablePrefixName": GetTablePrefixName}). 439 | Parse(genfunc.GetGenLogicTemp()) 440 | if err != nil { 441 | panic(err) 442 | } 443 | var buf bytes.Buffer 444 | tmpl.Execute(&buf, data) 445 | 446 | pkg.AddFuncStr(buf.String()) 447 | genOut = append(genOut, GenOutInfo{ 448 | FileName: fmt.Sprintf(m.info.DbName+".gen.%v.go", tab.Name), 449 | FileCtx: pkg.Generate(), 450 | }) 451 | } 452 | 453 | return 454 | } 455 | -------------------------------------------------------------------------------- /data/view/model/model_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/xxjwxc/gormt/data/config" 7 | "testing" 8 | ) 9 | 10 | func TestTypeName(t *testing.T) { 11 | fmt.Println(getTypeName("tinyint", true)) 12 | } 13 | 14 | func TestTools(t *testing.T) { 15 | str := `{"DbName":"oauth_db","PackageName":"model","TabList":[{"Name":"user_account_tbl","Notes":"用户账号","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"account","Notes":"","Type":"varchar(64)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"password","Notes":"","Type":"varchar(64)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"account_type","Notes":"帐号类型:0手机号,1邮件","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"authbucket_oauth2_client表的id","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"user_info_tbl_id","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":"user_info_id"}],"IsNull":false,"ForeignKeyList":[{"TableName":"user_info_tbl","ColumnName":"id"}]},{"Name":"reg_time","Notes":"","Type":"datetime","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"reg_ip","Notes":"","Type":"varchar(15)","Index":[{"Key":3,"KeyName":"user_info_id"}],"IsNull":true,"ForeignKeyList":null},{"Name":"bundle_id","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"describ","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"user_info_tbl","Notes":"用户信息","SQLBuildStr":"","Em":[{"Name":"","Notes":"","Type":"gorm.Model","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"nickname","Notes":"","Type":"varchar(32)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"headurl","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"oauth2_access_token","Notes":"token认证","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"access_token","Notes":"","Type":"varchar(255)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"token_type","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"key","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"username","Notes":"用户名","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expires","Notes":"过期时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"user","Notes":"","SQLBuildStr":"","Em":[{"Name":"userId","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"name","Notes":"","Type":"varchar(30)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"sex","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"job","Notes":"","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"organ","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"userId","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":""}],"IsNull":true,"ForeignKeyList":[{"TableName":"user","ColumnName":"sex"}]},{"Name":"type","Notes":"","Type":"int(11)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"score","Notes":"","Type":"int(11)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"sign_client_tbl","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_secret","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expire_time","Notes":"超时时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"strict_sign","Notes":"是否强制验签:0:用户自定义,1:强制","Type":"int(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"strict_verify","Notes":"是否强制验证码:0:用户自定义,1:强制","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"token过期时间","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"user_paybill_order","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"paybill_id","Notes":"二次账单id","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_id_mysql","Notes":"MySql中的订单Id","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_item_id_mysql","Notes":"MySql中的订单ItemId","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_id_mssql","Notes":"MsSql中的订单Id","Type":"bigint(20)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"oauth2_client_tbl","Notes":"client key 信息","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_secret","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expire_time","Notes":"超时时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"strict_sign","Notes":"是否强制验签:0:用户自定义,1:强制","Type":"int(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"strict_verify","Notes":"是否强制验证码:0:用户自定义,1:强制","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"token过期时间","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"aaa","Notes":"","Type":"json","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"oauth2_refresh_token","Notes":"刷新token","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"refresh_token","Notes":"","Type":"varchar(255)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"token_type","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"username","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expires","Notes":"","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]}]}` 16 | var pkg DBInfo 17 | json.Unmarshal([]byte(str), &pkg) 18 | // out, _ := json.Marshal(pkg) 19 | // tools.WriteFile("test.txt", []string{string(out)}, true) 20 | 21 | config.SetIsWEBTag(true) 22 | config.SetIsOutFunc(false) 23 | list, _ := Generate(pkg) 24 | fmt.Println(list) 25 | 26 | config.SetForeignKey(true) 27 | list, _ = Generate(pkg) 28 | fmt.Println(list) 29 | } 30 | -------------------------------------------------------------------------------- /doc/export.md: -------------------------------------------------------------------------------- 1 | ## 目录 2 | - [sql code](#sql-code) 3 | - [Mult complex export without foreign key](#Mult-complex-export-without-foreign-key) 4 | - [Complex single table mode export](#Complex-single-table-mode-export) 5 | - [Simple export with JSON](#Simple-export-with-JSON) 6 | - [Simple export without JSON](#Simple-export-without-JSON) 7 | - [Simple with foreign key mode export](#Simple-with-foreign-key-mode-export) 8 | - [sql2](#sql2) 9 | - [Support export gorm.model](#Support export gorm.model) 10 | 11 | 12 | ### sql code 13 | 14 | - sql: 15 | ``` 16 | CREATE TABLE `user_account_tbl` ( 17 | `id` int(11) NOT NULL AUTO_INCREMENT, 18 | `account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 19 | `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 20 | `account_type` int(11) NOT NULL DEFAULT '0' COMMENT '[@gorm default:'123456']帐号类型:0手机号,1邮件', 21 | `app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id', 22 | `user_info_tbl_id` int(11) NOT NULL, 23 | `reg_time` datetime DEFAULT NULL, 24 | `reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 25 | `bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 26 | `describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 27 | PRIMARY KEY (`id`) USING BTREE, 28 | UNIQUE KEY `account` (`account`) USING BTREE, 29 | UNIQUE KEY `UNIQ_5696AD037D3656A4` (`app_key`,`user_info_tbl_id`) USING BTREE, 30 | KEY `user_info_id` (`user_info_tbl_id`) USING BTREE, 31 | CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT 32 | ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='[@gorm default:'admin']用户账号' 33 | ``` 34 | 35 | ------------- 36 | 37 | ### Mult complex export without foreign key 38 | 39 | - param: simple = false is_foreign_key = false 40 | 41 | ###### --->export result 42 | 43 | ``` 44 | // UserAccountTbl 用户账号 45 | type UserAccountTbl struct { 46 | ID int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"` 47 | Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"` 48 | Password string `gorm:"column:password;type:varchar(64);not null" json:"password"` 49 | AccountType int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号,1邮件 50 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null" json:"app_key"` // authbucket_oauth2_client表的id 51 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_tbl_id;type:int(11);not null" json:"user_info_tbl_id"` 52 | RegTime time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"` 53 | RegIP string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"` 54 | BundleID string `gorm:"column:bundle_id;type:varchar(255)" json:"bundle_id"` 55 | Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"` 56 | } 57 | ``` 58 | 59 | ------------- 60 | 61 | ### Simple-export-with-JSON 62 | 63 | - param: simple = true is_web_tag = true is_foreign_key = false 64 | 65 | ###### --->export result 66 | 67 | ``` 68 | // UserAccountTbl 用户账号 69 | type UserAccountTbl struct { 70 | ID int `gorm:"primary_key" json:"-"` 71 | Account string `gorm:"unique" json:"account"` 72 | Password string `json:"password"` 73 | AccountType int `json:"account_type"` // 帐号类型:0手机号,1邮件 74 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4" json:"app_key"` // authbucket_oauth2_client表的id 75 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index" json:"user_info_tbl_id"` 76 | RegTime time.Time `json:"reg_time"` 77 | RegIP string `json:"reg_ip"` 78 | BundleID string `json:"bundle_id"` 79 | Describ string `json:"describ"` 80 | } 81 | 82 | ``` 83 | -------------- 84 | 85 | ### Simple export without JSON 86 | 87 | - param: simple = true is_web_tag = false is_foreign_key = false 88 | 89 | ###### --->export result 90 | 91 | ``` 92 | // UserAccountTbl 用户账号 93 | type UserAccountTbl struct { 94 | ID int `gorm:"primary_key"` 95 | Account string `gorm:"unique"` 96 | Password string 97 | AccountType int // 帐号类型:0手机号,1邮件 98 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id 99 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` 100 | RegTime time.Time 101 | RegIP string 102 | BundleID string 103 | Describ string 104 | } 105 | ``` 106 | 107 | -------------- 108 | 109 | ### Simple with foreign key mode export 110 | 111 | - param: simple = true is_web_tag = false is_foreign_key = true 112 | 113 | ###### --->export result 114 | 115 | ``` 116 | // UserAccountTbl 用户账号 117 | type UserAccountTbl struct { 118 | ID int `gorm:"primary_key"` 119 | Account string `gorm:"unique"` 120 | Password string 121 | AccountType int // 帐号类型:0手机号,1邮件 122 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id 123 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` 124 | UserInfoTbl UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息 125 | RegTime time.Time 126 | RegIP string 127 | BundleID string 128 | Describ string 129 | } 130 | ``` 131 | 132 | -------------- 133 | 134 | ## sql2 135 | ``` 136 | CREATE TABLE `user_info_tbl` ( 137 | `id` int(11) NOT NULL AUTO_INCREMENT, 138 | `nickname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 139 | `headurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 140 | `created_at` datetime DEFAULT NULL, 141 | `updated_at` datetime DEFAULT NULL, 142 | `deleted_at` datetime DEFAULT NULL, 143 | PRIMARY KEY (`id`) USING BTREE, 144 | KEY `id` (`id`,`created_at`) 145 | ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户信息' 146 | ``` 147 | 148 | ### Support export gorm.model 149 | 150 | - param: simple = true is_web_tag = false 151 | 152 | ###### --->export result 153 | 154 | 155 | ``` 156 | // UserInfoTbl 用户信息 157 | type UserInfoTbl struct { 158 | gorm.Model 159 | Nickname string 160 | Headurl string 161 | } 162 | ``` -------------------------------------------------------------------------------- /doc/export_cn.md: -------------------------------------------------------------------------------- 1 | ## 目录 2 | - [sql 原语](#sql-原语) 3 | - [复杂不带外键导出](#复杂不带外键导出) 4 | - [复杂单表模式导出](#复杂单表模式导出) 5 | - [简单带json导出](#简单带json导出) 6 | - [简单不带json导出](#简单不带json导出) 7 | - [简单带外键模式导出](#简单带外键模式导出) 8 | - [sql2](#sql2) 9 | - [支持gorm.Model模式导出](#支持gorm.Model模式导出) 10 | 11 | 12 | ### sql 原语 13 | 14 | - sql: 15 | ``` 16 | CREATE TABLE `user_account_tbl` ( 17 | `id` int(11) NOT NULL AUTO_INCREMENT, 18 | `account` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 19 | `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 20 | `account_type` int(11) NOT NULL DEFAULT '0' COMMENT '[@gorm default:'123456']帐号类型:0手机号,1邮件', 21 | `app_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'authbucket_oauth2_client表的id', 22 | `user_info_tbl_id` int(11) NOT NULL, 23 | `reg_time` datetime DEFAULT NULL, 24 | `reg_ip` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 25 | `bundle_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL, 26 | `describ` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 27 | PRIMARY KEY (`id`) USING BTREE, 28 | UNIQUE KEY `account` (`account`) USING BTREE, 29 | UNIQUE KEY `UNIQ_5696AD037D3656A4` (`app_key`,`user_info_tbl_id`) USING BTREE, 30 | KEY `user_info_id` (`user_info_tbl_id`) USING BTREE, 31 | CONSTRAINT `user_account_tbl_ibfk_1` FOREIGN KEY (`user_info_tbl_id`) REFERENCES `user_info_tbl` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT 32 | ) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='[@gorm default:'admin']用户账号' 33 | ``` 34 | 35 | ------------- 36 | 37 | ### 复杂不带外键导出 38 | 39 | - 参数: simple = false is_foreign_key = false 40 | 41 | ###### --->导出结果 42 | 43 | ``` 44 | // UserAccountTbl 用户账号 45 | type UserAccountTbl struct { 46 | ID int `gorm:"primary_key;column:id;type:int(11);not null" json:"-"` 47 | Account string `gorm:"unique;column:account;type:varchar(64);not null" json:"account"` 48 | Password string `gorm:"column:password;type:varchar(64);not null" json:"password"` 49 | AccountType int `gorm:"column:account_type;type:int(11);not null" json:"account_type"` // 帐号类型:0手机号,1邮件 50 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4;column:app_key;type:varchar(255);not null" json:"app_key"` // authbucket_oauth2_client表的id 51 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index;column:user_info_tbl_id;type:int(11);not null" json:"user_info_tbl_id"` 52 | RegTime time.Time `gorm:"column:reg_time;type:datetime" json:"reg_time"` 53 | RegIP string `gorm:"column:reg_ip;type:varchar(15)" json:"reg_ip"` 54 | BundleID string `gorm:"column:bundle_id;type:varchar(255)" json:"bundle_id"` 55 | Describ string `gorm:"column:describ;type:varchar(255)" json:"describ"` 56 | } 57 | ``` 58 | 59 | ------------- 60 | 61 | ### 简单带json导出 62 | 63 | - 参数: simple = true is_web_tag = true is_foreign_key = false 64 | 65 | ###### --->导出结果 66 | 67 | ``` 68 | // UserAccountTbl 用户账号 69 | type UserAccountTbl struct { 70 | ID int `gorm:"primary_key" json:"-"` 71 | Account string `gorm:"unique" json:"account"` 72 | Password string `json:"password"` 73 | AccountType int `json:"account_type"` // 帐号类型:0手机号,1邮件 74 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4" json:"app_key"` // authbucket_oauth2_client表的id 75 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index" json:"user_info_tbl_id"` 76 | RegTime time.Time `json:"reg_time"` 77 | RegIP string `json:"reg_ip"` 78 | BundleID string `json:"bundle_id"` 79 | Describ string `json:"describ"` 80 | } 81 | 82 | ``` 83 | -------------- 84 | 85 | ### 简单不带json导出 86 | 87 | - 参数: simple = true is_web_tag = false is_foreign_key = false 88 | 89 | ###### --->导出结果 90 | 91 | ``` 92 | // UserAccountTbl 用户账号 93 | type UserAccountTbl struct { 94 | ID int `gorm:"primary_key"` 95 | Account string `gorm:"unique"` 96 | Password string 97 | AccountType int // 帐号类型:0手机号,1邮件 98 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id 99 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` 100 | RegTime time.Time 101 | RegIP string 102 | BundleID string 103 | Describ string 104 | } 105 | ``` 106 | 107 | -------------- 108 | 109 | ### 简单带外键模式导出 110 | 111 | - 参数: simple = true is_web_tag = false is_foreign_key = true 112 | 113 | ###### --->导出结果 114 | 115 | ``` 116 | // UserAccountTbl 用户账号 117 | type UserAccountTbl struct { 118 | ID int `gorm:"primary_key"` 119 | Account string `gorm:"unique"` 120 | Password string 121 | AccountType int // 帐号类型:0手机号,1邮件 122 | AppKey string `gorm:"unique_index:UNIQ_5696AD037D3656A4"` // authbucket_oauth2_client表的id 123 | UserInfoTblID int `gorm:"unique_index:UNIQ_5696AD037D3656A4;index"` 124 | UserInfoTbl UserInfoTbl `gorm:"association_foreignkey:user_info_tbl_id;foreignkey:id"` // 用户信息 125 | RegTime time.Time 126 | RegIP string 127 | BundleID string 128 | Describ string 129 | } 130 | ``` 131 | 132 | -------------- 133 | 134 | ## sql2 135 | ``` 136 | CREATE TABLE `user_info_tbl` ( 137 | `id` int(11) NOT NULL AUTO_INCREMENT, 138 | `nickname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 139 | `headurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, 140 | `created_at` datetime DEFAULT NULL, 141 | `updated_at` datetime DEFAULT NULL, 142 | `deleted_at` datetime DEFAULT NULL, 143 | PRIMARY KEY (`id`) USING BTREE, 144 | KEY `id` (`id`,`created_at`) 145 | ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用户信息' 146 | ``` 147 | 148 | ### 支持gorm.Model模式导出 149 | 150 | - 参数: simple = true is_web_tag = false 151 | 152 | ###### --->导出结果 153 | 154 | 155 | ``` 156 | // UserInfoTbl 用户信息 157 | type UserInfoTbl struct { 158 | gorm.Model 159 | Nickname string 160 | Headurl string 161 | } 162 | ``` 163 | 164 | ### 表注释 tag 165 | 166 | - 给列添加注释以`[@gorm default:'test']`开头即可 167 | - 比如`[@gorm default:'test';->;<-:create]这是注释内容` 表示默认值为'test',允许读,更新创建 168 | - 外键注释使用`[@fk tableName.columnName]这是注释内容` 表示关联到`tableName`的`columnName`列 169 | -------------------------------------------------------------------------------- /doc/func.md: -------------------------------------------------------------------------------- 1 | # func export readme 2 | - Note: the shortcut function is only an auxiliary function of Gorm. Currently only query function is supported 3 | ## Catalog 4 | - [_BaseMgr](#_BaseMgr) 5 | - [_BaseMgr](#_BaseMgr) 6 | - [SetCtx](#SetCtx) 7 | - [GetDB](#GetDB) 8 | - [GetIsRelated](#GetIsRelated) 9 | - [SetIsRelated](#SetIsRelated) 10 | - [Table logic function](#Table-logic-function) 11 | - [Brief description](#Brief-description) 12 | - [Basic types of logic]](#Basic-types-of-logic) 13 | - [Access to existing conditions](#Access-to-existing-conditions) 14 | - [Access to function options](#Access-to-function-options) 15 | - [Single element access](#Single-element-access) 16 | - [Index access](#Index-access) 17 | 18 | ## _BaseMgr 19 | 20 | ### OpenRelated : open global related 21 | ### CloseRelated : close global related 22 | 23 | Basic function. All management types inherit this function. This function provides the underlying common function. 24 | ### SetCtx 25 | Set context, which is used to set context. The current function is not enabled 26 | ### GetDB 27 | Get gorm.db original link 28 | ### UpdateDB 29 | Update gorm.db original link 30 | ### GetIsRelated 31 | Get whether to query foreign key Association 32 | ### SetIsRelated 33 | Set whether to query foreign key Association 34 | 35 | ## Table logic function 36 | Table logical function operation about database table related function: use [XXX] to represent logical table structure name 37 | ### Brief description 38 | Queries are divided into the following categories 39 | ### Basic types of logic 40 | `_[xxx]Mgr` : Logical table type 41 | ### Access to existing conditions 42 | `Get/Gets` : Batch get (you can use gormt to get the final result using its preset conditions) 43 | 44 | ### Access to function options 45 | 46 | This function is used to support multiple condition acquisition 47 | 48 | `GetByOption/GetByOptions` : Get function option list 49 | `With[xxx]` : Parameter list in function options 50 | 51 | ### Single element access 52 | 53 | `GetFrom[xxx]` : Element acquisition (single case conditional acquisition) 54 | 55 | `GetBatchFrom[xxx]` : Batch element acquisition (array acquisition of a single condition) 56 | 57 | ### Index access 58 | 59 | `FetchByPrimaryKey` : Primary key acquisition 60 | `FetchUniqueBy[xxx]` : Get by unique index 61 | `FetchIndexBy[xxx]` : Composite index fetch (multiple returned) 62 | `FetchUniqueIndexBy[xxx]` : Unique composite index fetch (return one) -------------------------------------------------------------------------------- /doc/func_cn.md: -------------------------------------------------------------------------------- 1 | # 快捷函数功能 2 | - 说明: 快捷函数只是对 gorm 的辅助功能。目前只支持查询功能 3 | ## 目录 4 | - [_BaseMgr](#_BaseMgr) 5 | - [_BaseMgr](#_BaseMgr) 6 | - [SetCtx](#SetCtx) 7 | - [GetDB](#GetDB) 8 | - [GetIsRelated](#GetIsRelated) 9 | - [SetIsRelated](#SetIsRelated) 10 | - [表逻辑函数](#表逻辑函数) 11 | - [简要说明](#简要说明) 12 | - [逻辑基础类型]](#逻辑基础类型) 13 | - [已有条件获取方式](#已有条件获取方式) 14 | - [功能选项方式获取](#功能选项方式获取) 15 | - [单元素方式获取](#单元素方式获取) 16 | - [索引方式获取](#索引方式获取) 17 | 18 | ## _BaseMgr 19 | ### OpenRelated : 打开全局预加载 20 | ### CloseRelated : 关闭全局预加载 21 | 基础函数。所有管理类型都是继承此函数。此函数提供基础公共函数。 22 | ### SetCtx 23 | 设置 context ,用于设置上下文。目前功能未启用 24 | ### GetDB 25 | 获取 gorm.DB 原始链接窜 26 | ### UpdateDB 27 | 更新 gorm.DB 原始链接窜 28 | ### GetIsRelated 29 | 获取是否查询外键关联 30 | ### SetIsRelated 31 | 设置是否查询外键关联 32 | 33 | ## 表逻辑函数 34 | 表逻辑函数操作关于数据库表相关功能函数:以下使用[xxx]代表逻辑表结构体名 35 | ### 简要说明 36 | 查询分为以下几类 37 | ### 逻辑基础类型 38 | `_[xxx]Mgr` : 逻辑表类型 39 | ### 已有条件获取方式 40 | `Get/Gets` : 批量获取(使用 gormt 预先设置的条件可以使用它来获取最终结果) 41 | ### 功能选项方式获取 42 | 43 | 此功能 用于支持多种条件获取 44 | 45 | `GetByOption/GetByOptions` : 功能选项列表获取 46 | `With[xxx]` : 功能选项中的参数列表 47 | 48 | ### 单元素方式获取 49 | 50 | `GetFrom[xxx]` : 元素获取(单个case条件获取) 51 | 52 | `GetBatchFrom[xxx]` : 批量元素获取(单个条件的数组获取) 53 | 54 | ### 索引方式获取 55 | `FetchByPrimaryKey` : 主键获取 56 | `FetchUniqueBy[xxx]` : 唯一索引方式获取 57 | `FetchIndexBy[xxx]` : 复合索引获取(返回多个) 58 | `FetchUniqueIndexBy[xxx]` : 唯一复合索引获取(返回一个) -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/xxjwxc/gormt 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/jroimartin/gocui v0.4.0 7 | github.com/nicksnyder/go-i18n/v2 v2.0.3 8 | github.com/spf13/cobra v1.0.0 9 | github.com/xxjwxc/public v0.0.0-20230522110634-c12fa2a731cf 10 | golang.org/x/text v0.21.0 11 | gopkg.in/go-playground/validator.v9 v9.30.2 12 | gopkg.in/yaml.v3 v3.0.1 13 | gorm.io/driver/mysql v1.0.1 14 | gorm.io/driver/sqlite v1.5.1 15 | gorm.io/driver/sqlserver v1.5.0 16 | gorm.io/gorm v1.25.2-0.20230521132722-001738be49d2 17 | ) 18 | 19 | require ( 20 | github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect 21 | github.com/go-playground/locales v0.14.1 // indirect 22 | github.com/go-playground/universal-translator v0.18.1 // indirect 23 | github.com/go-sql-driver/mysql v1.5.0 // indirect 24 | github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect 25 | github.com/golang-sql/sqlexp v0.1.0 // indirect 26 | github.com/gookit/color v1.2.5 // indirect 27 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 28 | github.com/jinzhu/inflection v1.0.0 // indirect 29 | github.com/jinzhu/now v1.1.5 // indirect 30 | github.com/leodido/go-urn v1.2.4 // indirect 31 | github.com/mattn/go-runewidth v0.0.9 // indirect 32 | github.com/mattn/go-sqlite3 v1.14.16 // indirect 33 | github.com/microsoft/go-mssqldb v0.21.0 // indirect 34 | github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 // indirect 35 | github.com/pkg/errors v0.9.1 // indirect 36 | github.com/spf13/pflag v1.0.3 // indirect 37 | go.uber.org/atomic v1.7.0 // indirect 38 | go.uber.org/multierr v1.1.0 // indirect 39 | go.uber.org/zap v1.10.0 // indirect 40 | golang.org/x/crypto v0.31.0 // indirect 41 | gopkg.in/go-playground/assert.v1 v1.2.1 // indirect 42 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect 43 | ) 44 | 45 | // replace github.com/xxjwxc/public => ../public 46 | -------------------------------------------------------------------------------- /gogenerate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //go:generate make mac 4 | //go:generate make windows 5 | //go:generate make linux 6 | -------------------------------------------------------------------------------- /image/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/.DS_Store -------------------------------------------------------------------------------- /image/gormt/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/1.png -------------------------------------------------------------------------------- /image/gormt/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/2.jpg -------------------------------------------------------------------------------- /image/gormt/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/3.jpg -------------------------------------------------------------------------------- /image/gormt/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/4.jpg -------------------------------------------------------------------------------- /image/gormt/out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/out.gif -------------------------------------------------------------------------------- /image/gormt/ui_cn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/ui_cn.gif -------------------------------------------------------------------------------- /image/gormt/ui_en.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xxjwxc/gormt/bce2e5005d27a83c7f2926ba195b2c396d89f2ca/image/gormt/ui_en.gif -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "github.com/xxjwxc/gormt/data/cmd" 4 | 5 | func main() { 6 | cmd.Execute() 7 | } 8 | -------------------------------------------------------------------------------- /main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/xxjwxc/gormt/data/view/model" 9 | ) 10 | 11 | func TestMain(t *testing.T) { 12 | str := `{"DbName":"oauth_db","PackageName":"model","TabList":[{"Name":"user_account_tbl","Notes":"用户账号","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"account","Notes":"","Type":"varchar(64)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"password","Notes":"","Type":"varchar(64)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"account_type","Notes":"帐号类型:0手机号,1邮件","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"authbucket_oauth2_client表的id","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"user_info_tbl_id","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":"user_info_id"}],"IsNull":false,"ForeignKeyList":[{"TableName":"user_info_tbl","ColumnName":"id"}]},{"Name":"reg_time","Notes":"","Type":"datetime","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"reg_ip","Notes":"","Type":"varchar(15)","Index":[{"Key":3,"KeyName":"user_info_id"}],"IsNull":true,"ForeignKeyList":null},{"Name":"bundle_id","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"describ","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"user_info_tbl","Notes":"用户信息","SQLBuildStr":"","Em":[{"Name":"","Notes":"","Type":"gorm.Model","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"nickname","Notes":"","Type":"varchar(32)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"headurl","Notes":"","Type":"varchar(255)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"oauth2_access_token","Notes":"token认证","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"access_token","Notes":"","Type":"varchar(255)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"token_type","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"key","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"username","Notes":"用户名","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expires","Notes":"过期时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"user","Notes":"","SQLBuildStr":"","Em":[{"Name":"userId","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"name","Notes":"","Type":"varchar(30)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"sex","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"job","Notes":"","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"organ","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"userId","Notes":"","Type":"int(11)","Index":[{"Key":3,"KeyName":""}],"IsNull":true,"ForeignKeyList":[{"TableName":"user","ColumnName":"sex"}]},{"Name":"type","Notes":"","Type":"int(11)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"score","Notes":"","Type":"int(11)","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"sign_client_tbl","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_secret","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expire_time","Notes":"超时时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"strict_sign","Notes":"是否强制验签:0:用户自定义,1:强制","Type":"int(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"strict_verify","Notes":"是否强制验证码:0:用户自定义,1:强制","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"token过期时间","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"user_paybill_order","Notes":"","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"paybill_id","Notes":"二次账单id","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_id_mysql","Notes":"MySql中的订单Id","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_item_id_mysql","Notes":"MySql中的订单ItemId","Type":"bigint(20)","Index":[{"Key":3,"KeyName":"order_id"}],"IsNull":false,"ForeignKeyList":null},{"Name":"order_id_mssql","Notes":"MsSql中的订单Id","Type":"bigint(20)","Index":null,"IsNull":false,"ForeignKeyList":null}]},{"Name":"oauth2_client_tbl","Notes":"client key 信息","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_secret","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expire_time","Notes":"超时时间","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"strict_sign","Notes":"是否强制验签:0:用户自定义,1:强制","Type":"int(255)","Index":null,"IsNull":true,"ForeignKeyList":null},{"Name":"strict_verify","Notes":"是否强制验证码:0:用户自定义,1:强制","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"token过期时间","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"aaa","Notes":"","Type":"json","Index":null,"IsNull":true,"ForeignKeyList":null}]},{"Name":"oauth2_refresh_token","Notes":"刷新token","SQLBuildStr":"","Em":[{"Name":"id","Notes":"","Type":"int(11)","Index":[{"Key":1,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"refresh_token","Notes":"","Type":"varchar(255)","Index":[{"Key":2,"KeyName":""}],"IsNull":false,"ForeignKeyList":null},{"Name":"token_type","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"app_key","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"username","Notes":"","Type":"varchar(255)","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"expires","Notes":"","Type":"datetime","Index":null,"IsNull":false,"ForeignKeyList":null},{"Name":"token_expire_time","Notes":"","Type":"int(11)","Index":null,"IsNull":false,"ForeignKeyList":null}]}]}` 13 | var pkg model.DBInfo 14 | json.Unmarshal([]byte(str), &pkg) 15 | // out, _ := json.Marshal(pkg) 16 | // tools.WriteFile("test.txt", []string{string(out)}, true) 17 | 18 | list, _ := model.Generate(pkg) 19 | fmt.Println(list) 20 | } 21 | -------------------------------------------------------------------------------- /sql.yml: -------------------------------------------------------------------------------- 1 | dbname: caoguo_db # 数据库名 2 | comment: 潮果 # 数据库描述 3 | dbs: [mysql] # 数据库类型 4 | tables: # 数据库表 5 | name: product_tbl # 表名 6 | comment: 递增Id # 表注释 7 | columns: # 表列信息 8 | [ 9 | name: id , # 列名 10 | comment: 递增Id, # 列注释 11 | isnull: false , # 是否为空 12 | type: bigint(20) , # 类型 13 | default: 10, # 默认值 14 | klist: 15 | [ 16 | key: ColumnsKeyPrimary, 17 | multi: true, # 是否多个(复合组建) 18 | keyname: test, 19 | ], 20 | foreignkey: # 外键 21 | [ 22 | tablename: product_tbl, # 该索引受影响的表 23 | columnname: id # 该索引受影响的表的哪一列 24 | ] 25 | ],[ 26 | name: id , # 列名 27 | comment: 递增Id, # 列注释 28 | isnull: false , # 是否为空 29 | type: bigint(20) , # 类型 30 | default: 10, # 默认值 31 | klist: 32 | [ 33 | key: ColumnsKeyPrimary, 34 | multi: true, # 是否多个(复合组建) 35 | keyname: test, 36 | ] 37 | foreignkey: # 外键 38 | [ 39 | tablename: product_tbl, # 该索引受影响的表 40 | columnname: id # 该索引受影响的表的哪一列 41 | ] 42 | ] --------------------------------------------------------------------------------