From a88fc51a4a7fc63b2c6018c013c41e1c11b2b527 Mon Sep 17 00:00:00 2001 From: tangpanqing Date: Sun, 25 Dec 2022 16:39:59 +0800 Subject: [PATCH] support mssql --- README.md | Bin 44006 -> 44006 bytes README_zh.md | Bin 41358 -> 41358 bytes migrate_mssql/migrate.go | 4 +- migrate_postgres/migrate.go | 162 ++++++++++++++++++++++++++---------- test/aorm_test.go | 30 +++---- 5 files changed, 135 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 675ae01d9758b1c17d593db84b58f265082e4bb9..2917822220ec31193f6b28060a9a2c33703a3cad 100644 GIT binary patch delta 907 zcmaEMo$1+irVU1d?0F2O3^@!rlYa}zPmU1GgY(Y{&V{oJg__~)-zaSB$p?hJ;BtZ@ zopAO-k!mEi{A4H5Y2i@281xuC8S)rP7!nwC7!-gcLOd8KTEvhE6iLS->%@=`ggNLk zll8?!VRmiy7Auv6aV9%@NKfuCvw`yuT8d77U}gp9E1J6_v4tlmw6jcpV4w#VTW=K! zXFoI)pWI{U2jg#kXxPdE$2T=1j2Cyc$>(c>dRHPD#N z5#DzY0>IeW9Of5*5SZ8{zxhnSDq)!Z$+an_F!tu1DWVcE&Sa2TUuudFT0sIm^=_yF zKN^$Z0-FEd3`GpNlYa}zPmU1GgY(Y{&V{oJg__~)-zaSB$p?hJ;BtZ@ zopAO-k!mEi{A4H5X_E!SIsEk)JQ?yBN*EFtbQlzXB-DNeJ%(VQXc0puP&OTltP{|k z`3yPeGL!YiL}B)9_7*FZgmET2dPq<1FtdU44_b;&eqd$==PR1KBe8`iC$zIneqf*n z7h7)?31>ev6rbE<=m+C(erVXr0^`uqqR9^p(f|0vghLNn`oiTX z@D$9h&F`%1SSL?g$~XCkyTs%#H3E|-r1NZE=lF~XEU0150}Lvz%{yF-n4zkiVAgMT z^!Nx-1=PAZ!ut*rOa>H4o5TD9AhI*MBsQN3SS1XXtxYk7u{ZBb5tV>hzxhi|5yHTp zdN%~;M`IG0vpJ*X9z+!AvdszYT3}agp3&t65e3=B(W{5x#Ppj$I6o#!ZQe1_2+Z01 jWAZw7m=nN`Ju!O@Bh(o}lUwEnAxVOQpKr6kylcDw1jZ3b diff --git a/README_zh.md b/README_zh.md index 0295984109d2531d750e6d35c74e5e734905a4a8..cac2ecbf72ffa014e28eec3f9d0e33147969f086 100644 GIT binary patch delta 892 zcmeA>%+z<7X@egRdmck6Lk>gE-ex#^A)oc+AU+Qyek+`< z%ijrS+Y87~zQZ4b#Gfw@wTnTI!IL46p@boUL5D#BNW$FkS3ukrp~i_J9|&{MRRMLo z0Y&o}60w*NDCo`fy?gUK!5boQn-}VY!`c6J{NZdvb$2AT@Z?nnMsWUn-AFjwUoRET zUT>H_`9VF;W-iSM%y2>KT2MS$Pd^RGZ0X4XQzRyTkms2EKt}>D{$EFQGM9k`oKJ>l zHm^5a%8D?+L4I?U`6ecWfV%MHyc({}0alNY1RdljN7!n?6)n^OIge}eI@=n!qRoa5 zOW~Z!Koy&RIB_5e)XQ&HbL|j@oAEJ1bh4f<-{cz+LNKw-A0x66el-MIT4gSOZ3oL8d*kF?DT>nq{1n-!bN;hf0}fezf) x5`ijU(;kK@u%pwB1Lj%+z<7X@egRdm=+VLlHyn-ex#^A)oc+AU+Qyek+`< z%ijrS+Y87~zQZ4b#Gfw@wTnTI!IL46p@boUL5D#BNW$FkS3ukrp~ea5vV4XdbX7pz zZa~p|pe{@k0tLO9f~IetCwM~yZu3H&a5($Fjz64jsP2x$7M{GyzzEKNuNw(x`|G8` z+3O9{CqJm?+03Omff+7HT?>jQ>*=QlAwe9wJI diff --git a/migrate_mssql/migrate.go b/migrate_mssql/migrate.go index ac5ba97..e3fbc10 100644 --- a/migrate_mssql/migrate.go +++ b/migrate_mssql/migrate.go @@ -65,9 +65,9 @@ func (mm *MigrateExecutor) MigrateCommon(tableName string, typeOf reflect.Type) if len(tablesFromDb) != 0 { tableFromDb := tablesFromDb[0] columnsFromDb := mm.getColumnsFromDb(dbName, tableName) - indexsFromDb := mm.getIndexesFromDb(tableName) + indexesFromDb := mm.getIndexesFromDb(tableName) - mm.modifyTable(tableFromCode, columnsFromCode, indexesFromCode, tableFromDb, columnsFromDb, indexsFromDb) + mm.modifyTable(tableFromCode, columnsFromCode, indexesFromCode, tableFromDb, columnsFromDb, indexesFromDb) } else { mm.createTable(tableFromCode, columnsFromCode, indexesFromCode) } diff --git a/migrate_postgres/migrate.go b/migrate_postgres/migrate.go index 5c2a199..3d23c02 100644 --- a/migrate_postgres/migrate.go +++ b/migrate_postgres/migrate.go @@ -7,10 +7,19 @@ import ( "github.com/tangpanqing/aorm/model" "github.com/tangpanqing/aorm/null" "reflect" + "regexp" "strconv" "strings" ) +type PgIndexes struct { + Schemaname null.String + Tablename null.String + Indexname null.String + Tablespace null.String + Indexdef null.String +} + type Table struct { TableName null.String TableComment null.String @@ -61,7 +70,6 @@ func (mm *MigrateExecutor) MigrateCommon(tableName string, typeOf reflect.Type) if dbErr != nil { return dbErr } - fmt.Println("dbName:" + dbName) tablesFromDb := mm.getTableFromDb(dbName, tableName) if len(tablesFromDb) != 0 { @@ -172,8 +180,12 @@ func (mm *MigrateExecutor) getColumnsFromDb(dbName string, tableName string) []C mm.Ex.RawSql(sqlColumn).GetMany(&columnsFromDb) for j := 0; j < len(columnsFromDb); j++ { - if columnsFromDb[j].DataType.String == "text" && columnsFromDb[j].MaxLength.Int64 == 65535 { - columnsFromDb[j].MaxLength = null.IntFrom(0) + if columnsFromDb[j].DataType.String == "character varying" { + columnsFromDb[j].DataType = null.StringFrom("varchar") + } + + if columnsFromDb[j].DataType.String == "double precision" { + columnsFromDb[j].DataType = null.StringFrom("float") } } @@ -181,18 +193,46 @@ func (mm *MigrateExecutor) getColumnsFromDb(dbName string, tableName string) []C } func (mm *MigrateExecutor) getIndexesFromDb(tableName string) []Index { - sqlIndex := "SHOW INDEXES FROM " + tableName + sqlIndex := "select * from pg_indexes where tablename=" + "'" + tableName + "'" + var sqliteMasterList []PgIndexes + mm.Ex.RawSql(sqlIndex).GetMany(&sqliteMasterList) - var indexsFromDb []Index - mm.Ex.RawSql(sqlIndex).GetMany(&indexsFromDb) + var indexesFromDb []Index + for i := 0; i < len(sqliteMasterList); i++ { + indexName := sqliteMasterList[i].Indexname.String + sql := sqliteMasterList[i].Indexdef.String - return indexsFromDb + t := 1 + if strings.Index(sql, "UNIQUE") != -1 { + t = 0 + } + + compileRegex := regexp.MustCompile("INDEX\\s(.*?)\\sON.*?\\((.*?)\\)") + matchArr := compileRegex.FindAllStringSubmatch(sql, -1) + + //主键索引 + if indexName == tableName+"_pkey" { + indexesFromDb = append(indexesFromDb, Index{ + NonUnique: null.IntFrom(int64(t)), + ColumnName: null.StringFrom(matchArr[0][2]), + KeyName: null.StringFrom("PRIMARY"), + }) + } else { + indexesFromDb = append(indexesFromDb, Index{ + NonUnique: null.IntFrom(int64(t)), + ColumnName: null.StringFrom(matchArr[0][2]), + KeyName: null.StringFrom(matchArr[0][1]), + }) + } + } + + return indexesFromDb } func (mm *MigrateExecutor) modifyTable(tableFromCode Table, columnsFromCode []Column, indexesFromCode []Index, tableFromDb Table, columnsFromDb []Column, indexesFromDb []Index) { - if tableFromCode.TableComment != tableFromDb.TableComment { - mm.modifyTableComment(tableFromCode) - } + //if tableFromCode.TableComment != tableFromDb.TableComment { + // mm.modifyTableComment(tableFromCode) + //} for i := 0; i < len(columnsFromCode); i++ { isFind := 0 @@ -200,14 +240,14 @@ func (mm *MigrateExecutor) modifyTable(tableFromCode Table, columnsFromCode []Co for j := 0; j < len(columnsFromDb); j++ { columnDb := columnsFromDb[j] - if columnCode.ColumnName == columnDb.ColumnName { + if columnCode.ColumnName.String == columnDb.ColumnName.String { isFind = 1 - if columnCode.DataType.String != columnDb.DataType.String || - columnCode.MaxLength.Int64 != columnDb.MaxLength.Int64 || - columnCode.ColumnComment.String != columnDb.ColumnComment.String || - columnCode.Extra.String != columnDb.Extra.String || - columnCode.ColumnDefault.String != columnDb.ColumnDefault.String { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getColumnStr(columnCode) + if columnCode.DataType.String != columnDb.DataType.String { + fmt.Println(columnCode.ColumnName.String, columnCode.DataType.String, columnDb.DataType.String) + + sql := "ALTER TABLE " + tableFromCode.TableName.String + " alter COLUMN " + getColumnStr(columnCode, "type") + //fmt.Println(sql) + _, err := mm.Ex.Exec(sql) if err != nil { fmt.Println(err) @@ -219,7 +259,7 @@ func (mm *MigrateExecutor) modifyTable(tableFromCode Table, columnsFromCode []Co } if isFind == 0 { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getColumnStr(columnCode) + sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getColumnStr(columnCode, "") _, err := mm.Ex.Exec(sql) if err != nil { fmt.Println(err) @@ -250,13 +290,7 @@ func (mm *MigrateExecutor) modifyTable(tableFromCode Table, columnsFromCode []Co } if isFind == 0 { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getIndexStr(indexCode) - _, err := mm.Ex.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("增加索引:" + sql) - } + mm.createIndex(tableFromCode.TableName.String, indexCode) } } } @@ -276,15 +310,17 @@ func (mm *MigrateExecutor) createTable(tableFromCode Table, columnsFromCode []Co for i := 0; i < len(columnsFromCode); i++ { column := columnsFromCode[i] - fieldArr = append(fieldArr, getColumnStr(column)) + fieldArr = append(fieldArr, getColumnStr(column, "")) } for i := 0; i < len(indexesFromCode); i++ { index := indexesFromCode[i] - fieldArr = append(fieldArr, getIndexStr(index)) + if index.KeyName.String == "PRIMARY" { + fieldArr = append(fieldArr, "PRIMARY KEY ("+index.ColumnName.String+")") + } } - sqlStr := "CREATE TABLE `" + tableFromCode.TableName.String + "` (\n" + strings.Join(fieldArr, ",\n") + "\n) " + " COMMENT " + tableFromCode.TableComment.String + ";" + sqlStr := "CREATE TABLE " + tableFromCode.TableName.String + " (\n" + strings.Join(fieldArr, ",\n") + "\n) " + ";" fmt.Println(sqlStr) _, err := mm.Ex.Exec(sqlStr) @@ -293,6 +329,29 @@ func (mm *MigrateExecutor) createTable(tableFromCode Table, columnsFromCode []Co } else { fmt.Println("创建表:" + tableFromCode.TableName.String) } + + //创建其他索引 + for i := 0; i < len(indexesFromCode); i++ { + index := indexesFromCode[i] + if index.KeyName.String != "PRIMARY" { + mm.createIndex(tableFromCode.TableName.String, index) + } + } +} + +func (mm *MigrateExecutor) createIndex(tableName string, index Index) { + keyType := "" + if index.NonUnique.Int64 == 0 { + keyType = "UNIQUE" + } + + sql := "CREATE " + keyType + " INDEX " + index.KeyName.String + " on " + tableName + " (" + index.ColumnName.String + ")" + _, err := mm.Ex.Exec(sql) + if err != nil { + fmt.Println(err) + } else { + fmt.Println("增加索引:" + sql) + } } func (mm *MigrateExecutor) getOpinionVal(key string, def string) string { @@ -321,17 +380,23 @@ func getTagMap(fieldTag string) map[string]string { return fieldMap } -func getColumnStr(column Column) string { +func getColumnStr(column Column, f string) string { var strArr []string strArr = append(strArr, column.ColumnName.String) - if column.MaxLength.Int64 == 0 { - if column.DataType.String == "varchar" { - strArr = append(strArr, column.DataType.String+"(255)") - } else { - strArr = append(strArr, column.DataType.String) - } + + //类型 + if column.Extra.String == "auto_increment" { + strArr = append(strArr, "serial") } else { - strArr = append(strArr, column.DataType.String+"("+strconv.Itoa(int(column.MaxLength.Int64))+")") + if column.MaxLength.Int64 == 0 { + if column.DataType.String == "varchar" { + strArr = append(strArr, column.DataType.String+"(255)") + } else { + strArr = append(strArr, f+" "+column.DataType.String) + } + } else { + strArr = append(strArr, column.DataType.String+"("+strconv.Itoa(int(column.MaxLength.Int64))+")") + } } if column.ColumnDefault.String != "" { @@ -339,15 +404,15 @@ func getColumnStr(column Column) string { } if column.IsNullable.String == "NO" { - strArr = append(strArr, "NOT NULL") + //strArr = append(strArr, "NOT NULL") } if column.ColumnComment.String != "" { - strArr = append(strArr, "COMMENT '"+column.ColumnComment.String+"'") + //strArr = append(strArr, "COMMENT '"+column.ColumnComment.String+"'") } if column.Extra.String != "" { - strArr = append(strArr, column.Extra.String) + //strArr = append(strArr, column.Extra.String) } return strings.Join(strArr, " ") @@ -359,16 +424,16 @@ func getIndexStr(index Index) string { if "PRIMARY" == index.KeyName.String { strArr = append(strArr, index.KeyName.String) strArr = append(strArr, "KEY") - strArr = append(strArr, "(`"+index.ColumnName.String+"`)") + strArr = append(strArr, "("+index.ColumnName.String+")") } else { if 0 == index.NonUnique.Int64 { strArr = append(strArr, "Unique") strArr = append(strArr, index.KeyName.String) - strArr = append(strArr, "(`"+index.ColumnName.String+"`)") + strArr = append(strArr, "("+index.ColumnName.String+")") } else { strArr = append(strArr, "Index") strArr = append(strArr, index.KeyName.String) - strArr = append(strArr, "(`"+index.ColumnName.String+"`)") + strArr = append(strArr, "("+index.ColumnName.String+")") } } @@ -381,18 +446,25 @@ func getDataType(fieldType string, fieldMap map[string]string) string { dataTypeVal, dataTypeOk := fieldMap["type"] if dataTypeOk { DataType = dataTypeVal + if "tinyint" == DataType { + DataType = "integer" + } + if "double" == DataType { + DataType = "float" + } } else { if "Int" == fieldType { - DataType = "int" + DataType = "integer" } if "String" == fieldType { DataType = "varchar" } if "Bool" == fieldType { - DataType = "tinyint" + //DataType = "tinyint" + DataType = "boolean" } if "Time" == fieldType { - DataType = "datetime" + DataType = "date" } if "Float" == fieldType { DataType = "float" diff --git a/test/aorm_test.go b/test/aorm_test.go index 2a734ed..aeb8fbb 100644 --- a/test/aorm_test.go +++ b/test/aorm_test.go @@ -12,7 +12,6 @@ import ( "github.com/tangpanqing/aorm/helper" "github.com/tangpanqing/aorm/null" "testing" - "time" ) type Article struct { @@ -36,7 +35,7 @@ type Person struct { Sex null.Bool `aorm:"index;comment:性别" json:"sex"` Age null.Int `aorm:"index;comment:年龄" json:"age"` Type null.Int `aorm:"index;comment:类型" json:"type"` - CreateTime null.Time `aorm:"comment:创建时间" json:"createTime"` + CreateTime null.Int `aorm:"comment:创建时间" json:"createTime"` Money null.Float `aorm:"comment:金额" json:"money"` Test null.Float `aorm:"type:double;comment:测试" json:"test"` } @@ -52,7 +51,7 @@ type PersonWithArticleCount struct { Sex null.Bool `aorm:"index;comment:性别" json:"sex"` Age null.Int `aorm:"index;comment:年龄" json:"age"` Type null.Int `aorm:"index;comment:类型" json:"type"` - CreateTime null.Time `aorm:"comment:创建时间" json:"createTime"` + CreateTime null.Int `aorm:"comment:创建时间" json:"createTime"` Money null.Float `aorm:"comment:金额" json:"money"` Test null.Float `aorm:"type:double;comment:测试" json:"test"` ArticleCount null.Int `aorm:"comment:文章数量" json:"articleCount"` @@ -60,10 +59,10 @@ type PersonWithArticleCount struct { func TestAll(t *testing.T) { dbList := make([]aorm.DbContent, 0) - dbList = append(dbList, testSqlite3Connect()) - dbList = append(dbList, testMysqlConnect()) - //dbList = append(dbList, testPostgresConnect()) - dbList = append(dbList, testMssqlConnect()) + //dbList = append(dbList, testSqlite3Connect()) + //dbList = append(dbList, testMysqlConnect()) + dbList = append(dbList, testPostgresConnect()) + //dbList = append(dbList, testMssqlConnect()) for i := 0; i < len(dbList); i++ { dbItem := dbList[i] @@ -145,7 +144,10 @@ func testPostgresConnect() aorm.DbContent { panic(postgresErr) } - postgresContent.DbLink.Ping() + err := postgresContent.DbLink.Ping() + if err != nil { + panic(err) + } return postgresContent } @@ -184,12 +186,12 @@ func testInsert(name string, db *sql.DB) int64 { Sex: null.BoolFrom(false), Age: null.IntFrom(18), Type: null.IntFrom(0), - CreateTime: null.TimeFrom(time.Now()), - Money: null.FloatFrom(100.15), - Test: null.FloatFrom(200.15987654321987654321), + CreateTime: null.IntFrom(2), + Money: null.FloatFrom(1), + Test: null.FloatFrom(2), } - id, errInsert := aorm.Use(db).Debug(false).Driver(name).Insert(&obj) + id, errInsert := aorm.Use(db).Debug(true).Driver(name).Insert(&obj) if errInsert != nil { panic(name + " testInsert " + "found err: " + errInsert.Error()) } @@ -239,7 +241,7 @@ func testInsertBatch(name string, db *sql.DB) int64 { Sex: null.BoolFrom(false), Age: null.IntFrom(18), Type: null.IntFrom(0), - CreateTime: null.TimeFrom(time.Now()), + CreateTime: null.IntFrom(1111), Money: null.FloatFrom(100.15), Test: null.FloatFrom(200.15987654321987654321), }) @@ -249,7 +251,7 @@ func testInsertBatch(name string, db *sql.DB) int64 { Sex: null.BoolFrom(true), Age: null.IntFrom(18), Type: null.IntFrom(0), - CreateTime: null.TimeFrom(time.Now()), + CreateTime: null.IntFrom(1111), Money: null.FloatFrom(100.15), Test: null.FloatFrom(200.15987654321987654321), })