support sqlite

支持sqlite
This commit is contained in:
谢小军
2020-09-22 19:23:36 +08:00
parent 9893478fa8
commit 36b6de2a7b
18 changed files with 551 additions and 65 deletions

View File

@@ -0,0 +1,74 @@
package gensqlite
import (
"strings"
"github.com/xxjwxc/gormt/data/config"
"github.com/xxjwxc/gormt/data/view/model"
)
// filterModel filter.过滤 gorm.Model
func filterModel(list *[]genColumns) bool {
if config.GetDBTag() != "gorm" {
return false
}
var _temp []genColumns
num := 0
for _, v := range *list {
if strings.EqualFold(v.Name, "id") ||
strings.EqualFold(v.Name, "created_at") ||
strings.EqualFold(v.Name, "updated_at") ||
strings.EqualFold(v.Name, "deleted_at") {
num++
} else {
_temp = append(_temp, v)
}
}
if num >= 4 {
*list = _temp
return true
}
return false
}
// fixForeignKey fix foreign key.过滤外键
func fixForeignKey(list []genForeignKey, columuName string, result *[]model.ForeignKey) {
for _, v := range list {
if strings.EqualFold(v.ColumnName, columuName) { // find it .找到了
*result = append(*result, model.ForeignKey{
TableName: v.ReferencedTableName,
ColumnName: v.ReferencedColumnName,
})
}
}
}
// GetModel get model interface. 获取model接口
func GetModel() model.IModel {
//now just support mysql
return &SQLiteModel
}
// FixElementNote 分析元素表注释
func FixElementNote(em *model.ColumnsInfo, note string) {
matches := noteRegex.FindStringSubmatch(note)
if len(matches) < 2 {
em.Notes = note
return
}
em.Notes = note[len(matches[0]):]
list := strings.Split(matches[1], ";")
for _, v := range list {
tmp := strings.Split(v, ":")
if len(tmp) == 2 {
if strings.EqualFold(tmp[0], "default") { // 默认值
em.Default = tmp[1]
}
}
}
}

View File

@@ -0,0 +1,31 @@
package gensqlite
import "regexp"
type keys struct {
NonUnique int `gorm:"column:Non_unique"`
KeyName string `gorm:"column:Key_name"`
ColumnName string `gorm:"column:Column_name"`
}
// genColumns show full columns
type genColumns struct {
Name string `gorm:"column:name"`
Type string `gorm:"column:type"`
Pk int `gorm:"column:pk"`
NotNull int `gorm:"column:notnull"`
}
//select table_schema,table_name,column_name,referenced_table_schema,referenced_table_name,referenced_column_name from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
// where table_schema ='matrix' AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME = 'credit_card' ;
// genForeignKey Foreign key of db info . 表的外键信息
type genForeignKey struct {
TableSchema string `gorm:"column:table_schema"` // Database of columns.列所在的数据库
TableName string `gorm:"column:table_name"` // Data table of column.列所在的数据表
ColumnName string `gorm:"column:column_name"` // Column names.列名
ReferencedTableSchema string `gorm:"column:referenced_table_schema"` // The database where the index is located.该索引所在的数据库
ReferencedTableName string `gorm:"column:referenced_table_name"` // Affected tables . 该索引受影响的表
ReferencedColumnName string `gorm:"column:referenced_column_name"` // Which column of the affected table.该索引受影响的表的哪一列
}
var noteRegex = regexp.MustCompile(`^\[@gormt\s(\S+)+\]`)

View File

@@ -0,0 +1,197 @@
package gensqlite
import (
"fmt"
"sort"
"strings"
"github.com/xxjwxc/public/mylog"
"github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3"
"github.com/xxjwxc/gormt/data/config"
"github.com/xxjwxc/gormt/data/view/model"
"github.com/xxjwxc/public/tools"
)
// SQLiteModel mysql model from IModel
var SQLiteModel sqliteModel
type sqliteModel struct {
}
// GenModel get model.DBInfo info.获取数据库相关属性
func (m *sqliteModel) GenModel() model.DBInfo {
db, err := gorm.Open("sqlite3", config.GetDbInfo().Host)
if err != nil {
mylog.Error(err)
return model.DBInfo{}
}
defer db.Close()
var dbInfo model.DBInfo
m.getPackageInfo(db, &dbInfo)
dbInfo.PackageName = m.GetPkgName()
dbInfo.DbName = m.GetDbName()
return dbInfo
}
// GetDbName get database name.获取数据库名字
func (m *sqliteModel) GetDbName() string {
dir := config.GetDbInfo().Host
dir = strings.Replace(dir, "\\", "/", -1)
if len(dir) > 0 {
if dir[len(dir)-1] == '/' {
dir = dir[:(len(dir) - 1)]
}
}
var dbName string
list := strings.Split(dir, "/")
if len(list) > 0 {
dbName = list[len(list)-1]
}
list = strings.Split(dbName, ".")
if len(list) > 0 {
dbName = list[0]
}
if len(dbName) == 0 || dbName == "." {
panic(fmt.Sprintf("%v : db host config err.must file dir", dbName))
}
return dbName
}
// GetPkgName package names through config outdir configuration.通过config outdir 配置获取包名
func (m *sqliteModel) GetPkgName() string {
dir := config.GetOutDir()
dir = strings.Replace(dir, "\\", "/", -1)
if len(dir) > 0 {
if dir[len(dir)-1] == '/' {
dir = dir[:(len(dir) - 1)]
}
}
var pkgName string
list := strings.Split(dir, "/")
if len(list) > 0 {
pkgName = list[len(list)-1]
}
if len(pkgName) == 0 || pkgName == "." {
list = strings.Split(tools.GetModelPath(), "/")
if len(list) > 0 {
pkgName = list[len(list)-1]
}
}
return pkgName
}
func (m *sqliteModel) getPackageInfo(orm *gorm.DB, info *model.DBInfo) {
tabls := m.getTables(orm) // get table and notes
for tabName, notes := range tabls {
var tab model.TabInfo
tab.Name = tabName
tab.Notes = notes
if config.GetIsOutSQL() {
// Get create SQL statements.获取创建sql语句
rows, err := orm.Raw("SELECT tbl_name,sql FROM sqlite_master WHERE type='table' AND name = " + assemblyTable(tabName)).Rows()
//defer rows.Close()
if err == nil {
if rows.Next() {
var table, CreateTable string
rows.Scan(&table, &CreateTable)
tab.SQLBuildStr = CreateTable
}
}
rows.Close()
// ----------end
}
// build element.构造元素
tab.Em = m.getTableElement(orm, tabName)
// --------end
info.TabList = append(info.TabList, tab)
}
// sort tables
sort.Slice(info.TabList, func(i, j int) bool {
return info.TabList[i].Name < info.TabList[j].Name
})
}
// getTableElement Get table columns and comments.获取表列及注释
func (m *sqliteModel) getTableElement(orm *gorm.DB, tab string) (el []model.ColumnsInfo) {
var list []genColumns
// Get table annotations.获取表注释
orm.Raw(fmt.Sprintf("PRAGMA table_info(%v)", assemblyTable(tab))).Scan(&list)
// filter gorm.Model.过滤 gorm.Model
if filterModel(&list) {
el = append(el, model.ColumnsInfo{
Type: "gorm.Model",
})
}
// -----------------end
// ForeignKey
var foreignKeyList []genForeignKey
if config.GetIsForeignKey() {
}
// ------------------end
for _, v := range list {
var tmp model.ColumnsInfo
tmp.Name = v.Name
tmp.Type = v.Type
FixElementNote(&tmp, "")
if v.Pk == 1 { // 主键
tmp.Index = append(tmp.Index, model.KList{
Key: model.ColumnsKeyPrimary,
Multi: false,
})
}
tmp.IsNull = (v.NotNull != 1)
// ForeignKey
fixForeignKey(foreignKeyList, tmp.Name, &tmp.ForeignKeyList)
// -----------------end
el = append(el, tmp)
}
return
}
// getTables Get columns and comments.获取表列及注释
func (m *sqliteModel) getTables(orm *gorm.DB) map[string]string {
tbDesc := make(map[string]string)
// Get column names.获取列名
var tables []string
rows, err := orm.Raw("SELECT name FROM sqlite_master WHERE type='table'").Rows()
if err != nil {
if !config.GetIsGUI() {
fmt.Println(err)
}
return tbDesc
}
for rows.Next() {
var table string
rows.Scan(&table)
if !strings.EqualFold(table, "sqlite_sequence") { // 剔除系统默认
tables = append(tables, table)
tbDesc[table] = ""
}
}
rows.Close()
// TODO.获取表注释
return tbDesc
}
func assemblyTable(name string) string {
return "'" + name + "'"
}