Skip to content

Commit 8913992

Browse files
committed
v0.1.3 fix some error,add new command mode -m
1 parent d3f0345 commit 8913992

6 files changed

Lines changed: 162 additions & 57 deletions

File tree

cmd/app.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,28 @@ func LogError(logDir string, logName string, strContent string, errInfo error) {
129129
}
130130
}
131131

132+
func LogOutput(logDir string, logName string, strContent string) {
133+
f, errFile := os.OpenFile(logDir+"/"+logName+".log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
134+
if errFile != nil {
135+
log.Fatal(errFile)
136+
}
137+
defer func() {
138+
if errFile := f.Close(); errFile != nil {
139+
log.Fatal(errFile) // 或设置到函数返回值中
140+
}
141+
}()
142+
// create new buffer
143+
buffer := bufio.NewWriter(f)
144+
_, errFile = buffer.WriteString(strContent + "\n")
145+
if errFile != nil {
146+
log.Fatal(errFile)
147+
}
148+
// flush buffered data to the file
149+
if errFile := buffer.Flush(); errFile != nil {
150+
log.Fatal(errFile)
151+
}
152+
}
153+
132154
// StrVal
133155
// 获取变量的字符串值,目前用于interface类型转成字符串类型
134156
// 浮点型 3.0将会转换成字符串3, "3"

cmd/root.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
var log = logrus.New()
2828
var cfgFile string
2929
var selFromYml bool
30+
var metaData bool
3031

3132
var wg sync.WaitGroup
3233
var wg2 sync.WaitGroup
@@ -114,22 +115,24 @@ func startDataTransfer(connStr *connect.DbConnStr) {
114115
}
115116
//遍历tableMap,先遍历表,再遍历该表的sql切片集合
116117
migDataStart := time.Now()
117-
for tableName, sqlFullSplit := range tableMap { //获取单个表名
118-
colName, colType, tableNotExist := preMigData(tableName, sqlFullSplit) //获取单表的列名,列字段类型
119-
if !tableNotExist { //目标表存在就执行数据迁移
120-
// 遍历该表的sql切片(多个分页查询或者全表查询sql)
121-
for index, sqlSplitSql := range sqlFullSplit {
122-
log.Info("Table ", tableName, " total task ", len(sqlFullSplit))
123-
ch <- struct{}{} //在没有被接收的情况下,至多发送n个消息到通道则被阻塞,若缓存区满,则阻塞,这里相当于占位置排队
124-
wg.Add(1) // 每运行一个goroutine等待组加1
125-
go runMigration(logDir, index, tableName, sqlSplitSql, ch, colName, colType)
118+
if !metaData {
119+
for tableName, sqlFullSplit := range tableMap { //获取单个表名
120+
colName, colType, tableNotExist := preMigData(tableName, sqlFullSplit) //获取单表的列名,列字段类型
121+
if !tableNotExist { //目标表存在就执行数据迁移
122+
// 遍历该表的sql切片(多个分页查询或者全表查询sql)
123+
for index, sqlSplitSql := range sqlFullSplit {
124+
log.Info("Table ", tableName, " total task ", len(sqlFullSplit))
125+
ch <- struct{}{} //在没有被接收的情况下,至多发送n个消息到通道则被阻塞,若缓存区满,则阻塞,这里相当于占位置排队
126+
wg.Add(1) // 每运行一个goroutine等待组加1
127+
go runMigration(logDir, index, tableName, sqlSplitSql, ch, colName, colType)
128+
}
129+
} else { //目标表不存在就往通道写1
130+
log.Info("table not exists ", tableName)
126131
}
127-
} else { //目标表不存在就往通道写1
128-
log.Info("table not exists ", tableName)
129132
}
133+
// 这里等待上面所有迁移数据的goroutine协程任务完成才会接着运行下面的主程序,如果这里不wait,上面还在迁移行数据的goroutine会被强制中断
134+
wg.Wait()
130135
}
131-
// 这里等待上面所有迁移数据的goroutine协程任务完成才会接着运行下面的主程序,如果这里不wait,上面还在迁移行数据的goroutine会被强制中断
132-
wg.Wait()
133136
// 单独计算迁移表行数据的耗时
134137
migDataEnd := time.Now()
135138
migCost := migDataEnd.Sub(migDataStart)
@@ -534,6 +537,7 @@ func init() {
534537
cobra.OnInitialize(initConfig)
535538
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.example.yaml)")
536539
rootCmd.PersistentFlags().BoolVarP(&selFromYml, "selFromYml", "s", false, "select from yml true")
540+
rootCmd.PersistentFlags().BoolVarP(&metaData, "metaData", "m", false, "only output create meta script true")
537541
//rootCmd.PersistentFlags().BoolVarP(&tableOnly, "tableOnly", "t", false, "only create table true")
538542
}
539543

cmd/tablemeta.go

Lines changed: 73 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (tb *Table) TableCreate(logDir string, tblName string, ch chan struct{}) {
8484
}
8585
// 判断colDefaultValue的长度,如果len大于0说明就是有非null的默认值,如果len为0说明在源库的默认值就是null
8686
if len([]rune(colDefaultValue.String)) > 0 {
87-
newTable.columnDefault = colDefaultValue.String
87+
newTable.columnDefault = strings.ReplaceAll(colDefaultValue.String, "\n", "")
8888
} else {
8989
newTable.columnDefault = "null"
9090
}
@@ -120,6 +120,8 @@ func (tb *Table) TableCreate(logDir string, tblName string, ch chan struct{}) {
120120
matches := re.FindAllString(newTable.dataType, -1)
121121
if matches[0] == "TIMESTAMP" { //timestamp类型,才需要加精度值
122122
newTable.destDefault = "default current_timestamp(" + strconv.Itoa(newTable.numericScale) + ")"
123+
} else {
124+
newTable.destDefault = "default current_timestamp"
123125
}
124126
} else { // 其余默认值类型无需使用单引号包围
125127
newTable.destDefault = fmt.Sprintf("default %s", newTable.columnDefault)
@@ -166,17 +168,21 @@ func (tb *Table) TableCreate(logDir string, tblName string, ch chan struct{}) {
166168
}
167169
}
168170
//fmt.Println(createTblSql) // 打印创建表语句
169-
// 创建前先删除目标表
170-
dropDestTbl := "drop table if exists " + fmt.Sprintf("`") + tblName + fmt.Sprintf("`") + " cascade"
171-
if _, err = destDb.Exec(dropDestTbl); err != nil {
172-
log.Error("drop table ", tblName, " failed ", err)
173-
}
174-
// 创建表结构
175-
log.Info(fmt.Sprintf("%v Table total %s create table %s", time.Now().Format("2006-01-02 15:04:05.000000"), strconv.Itoa(tableCount), tblName))
176-
if _, err = destDb.Exec(createTblSql); err != nil {
177-
log.Error("table ", tblName, " create failed ", err)
178-
LogError(logDir, "tableCreateFailed", createTblSql, err)
179-
failedCount += 1
171+
LogOutput(logDir, "createSql", createTblSql+";")
172+
if !metaData {
173+
// 创建前先删除目标表
174+
dropDestTbl := "drop table if exists " + fmt.Sprintf("`") + tblName + fmt.Sprintf("`") + " cascade"
175+
if _, err = destDb.Exec(dropDestTbl); err != nil {
176+
log.Error("drop table ", tblName, " failed ", err)
177+
}
178+
// 创建表结构
179+
log.Info(fmt.Sprintf("%v Table total %s create table %s", time.Now().Format("2006-01-02 15:04:05.000000"), strconv.Itoa(tableCount), tblName))
180+
181+
if _, err = destDb.Exec(createTblSql); err != nil {
182+
log.Error("table ", tblName, " create failed ", err)
183+
LogError(logDir, "tableCreateFailed", createTblSql, err)
184+
failedCount += 1
185+
}
180186
}
181187
<-ch
182188
}
@@ -197,12 +203,15 @@ func (tb *Table) IdxCreate(logDir string, tableName string, ch chan struct{}, id
197203
if err := rows.Scan(&destIdxSql); err != nil {
198204
log.Error(err)
199205
}
206+
LogOutput(logDir, "createSql", destIdxSql)
200207
destIdxSql = "/* goapp */" + destIdxSql
201208
// 创建目标索引,主键、其余约束
202-
if _, err = destDb.Exec(destIdxSql); err != nil {
203-
log.Error("index ", destIdxSql, " create index failed ", err)
204-
LogError(logDir, "idxCreateFailed", destIdxSql, err)
205-
failedCount += 1
209+
if !metaData {
210+
if _, err = destDb.Exec(destIdxSql); err != nil {
211+
log.Error("index ", destIdxSql, " create index failed ", err)
212+
LogError(logDir, "idxCreateFailed", destIdxSql, err)
213+
failedCount += 1
214+
}
206215
}
207216
}
208217
if destIdxSql != "" {
@@ -244,18 +253,26 @@ func (tb *Table) SeqCreate(logDir string) (ret []string) {
244253
// 创建目标数据库该表表的自增列索引
245254
sqlAutoColIdx := "/* goapp */" + "create index ids_" + tableName + "_" + autoColName + "_" + strconv.Itoa(idx) + " on " + tableName + "(" + autoColName + ")"
246255
log.Info("[", idx, "] create auto_increment for table ", tableName)
247-
if _, err = destDb.Exec(sqlAutoColIdx); err != nil {
248-
log.Error(sqlAutoColIdx, " create index autoCol failed ", err)
249-
LogError(logDir, "AutoIdxCreateFailed", sqlAutoColIdx, err)
250-
failedCount += 1
256+
LogOutput(logDir, "createSql", sqlAutoColIdx+";")
257+
if !metaData {
258+
if _, err = destDb.Exec(sqlAutoColIdx); err != nil {
259+
log.Error(sqlAutoColIdx, " create index autoCol failed ", err)
260+
LogError(logDir, "AutoIdxCreateFailed", sqlAutoColIdx, err)
261+
failedCount += 1
262+
}
251263
}
264+
252265
// 更改目标数据库该表的列属性为自增列
253266
sqlModifyAuto := "/* goapp */" + "alter table " + tableName + " modify " + autoColName + " bigint auto_increment"
254-
if _, err = destDb.Exec(sqlModifyAuto); err != nil {
255-
log.Error(sqlModifyAuto, " failed ", err)
256-
LogError(logDir, "alterTableFailed", sqlModifyAuto, err)
257-
failedCount += 1
267+
LogOutput(logDir, "createSql", sqlModifyAuto+";")
268+
if !metaData {
269+
if _, err = destDb.Exec(sqlModifyAuto); err != nil {
270+
log.Error(sqlModifyAuto, " failed ", err)
271+
LogError(logDir, "alterTableFailed", sqlModifyAuto, err)
272+
failedCount += 1
273+
}
258274
}
275+
259276
}
260277
}
261278
}
@@ -283,10 +300,13 @@ func (tb *Table) FkCreate(logDir string) (ret []string) {
283300
}
284301
log.Info("[", idx, "] create foreign key for table ", tableName)
285302
sqlStr = "/* goapp */" + sqlStr
286-
if _, err = destDb.Exec(sqlStr); err != nil {
287-
log.Error(sqlStr, " create foreign key failed ", err)
288-
LogError(logDir, "FKCreateFailed", sqlStr, err)
289-
failedCount += 1
303+
LogOutput(logDir, "createSql", sqlStr)
304+
if !metaData {
305+
if _, err = destDb.Exec(sqlStr); err != nil {
306+
log.Error(sqlStr, " create foreign key failed ", err)
307+
LogError(logDir, "FKCreateFailed", sqlStr, err)
308+
failedCount += 1
309+
}
290310
}
291311
}
292312
endTime := time.Now()
@@ -322,11 +342,14 @@ func (tb *Table) NormalIdx(logDir string) (ret []string) {
322342
log.Error(err)
323343
}
324344
log.Info("[", idx, "] create normal index for table ", tableName)
345+
LogOutput(logDir, "createSql", createSql+";")
325346
createSql = "/* goapp */" + createSql
326-
if _, err = destDb.Exec(createSql); err != nil {
327-
log.Error(createSql, " create normal index failed ", err)
328-
LogError(logDir, "NormalIdxCreateFailed", createSql, err)
329-
failedCount += 1
347+
if !metaData {
348+
if _, err = destDb.Exec(createSql); err != nil {
349+
log.Error(createSql, " create normal index failed ", err)
350+
LogError(logDir, "NormalIdxCreateFailed", createSql, err)
351+
failedCount += 1
352+
}
330353
}
331354
}
332355

@@ -355,10 +378,13 @@ func (tb *Table) CommentCreate(logDir string) (ret []string) {
355378
}
356379
if len(createSql) > 0 { // 如果有normal-index,就通过dbms_metadata获取该normal-index的DDL语句
357380
log.Info("[", idx, "] create comment for table ", tableName)
358-
if _, err = destDb.Exec(createSql); err != nil {
359-
log.Error(createSql, " create comment failed ", err)
360-
LogError(logDir, "CommentCreateFailed", createSql, err)
361-
failedCount += 1
381+
LogOutput(logDir, "createSql", createSql+";")
382+
if !metaData {
383+
if _, err = destDb.Exec(createSql); err != nil {
384+
log.Error(createSql, " create comment failed ", err)
385+
LogError(logDir, "CommentCreateFailed", createSql, err)
386+
failedCount += 1
387+
}
362388
}
363389
}
364390

@@ -392,17 +418,21 @@ func (tb *Table) ViewCreate(logDir string) (ret []string) {
392418
dbRet = strings.ReplaceAll(dbRet, "--", "-- -- ")
393419
dbRet = strings.ReplaceAll(dbRet, "\"", "`")
394420
dbRet = strings.ReplaceAll(dbRet, "NVL(", "IFNULL(")
395-
dbRet = strings.ReplaceAll(dbRet, "unistr('\0030')", "0")
396-
dbRet = strings.ReplaceAll(dbRet, "unistr('\0031')", "1")
397-
dbRet = strings.ReplaceAll(dbRet, "unistr('\0033')", "3")
421+
dbRet = strings.ReplaceAll(dbRet, "UNISTR('\0030')", "0")
422+
dbRet = strings.ReplaceAll(dbRet, "UNISTR('\0031')", "1")
423+
dbRet = strings.ReplaceAll(dbRet, "UNISTR('\0033')", "3")
398424
if len(viewName) > 0 {
399425
sqlStr := "create or replace view " + viewName + " as " + dbRet
400426
log.Info("[", idx, "] create view ", viewName)
401-
if _, err = destDb.Exec(sqlStr); err != nil {
402-
//log.Error(sqlStr, " create view failed ", err)
403-
LogError(logDir, "ViewCreateFailed", sqlStr, err)
404-
failedCount += 1
427+
LogOutput(logDir, "createSql", sqlStr+";")
428+
if !metaData {
429+
if _, err = destDb.Exec(sqlStr); err != nil {
430+
//log.Error(sqlStr, " create view failed ", err)
431+
LogError(logDir, "ViewCreateFailed", sqlStr, err)
432+
failedCount += 1
433+
}
405434
}
435+
406436
}
407437
}
408438
endTime := time.Now()

cmd/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"github.com/spf13/cobra"
1010
)
1111

12-
var ver = "0.1.2"
12+
var ver = "0.1.3"
1313

1414
func init() {
1515
rootCmd.AddCommand(versionCmd)

readme.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,31 @@ e.g.
252252
OracleSync2MySQL.exe --config example.yml onlyData -s
253253
```
254254

255+
### 7 output create ddl
256+
257+
Do not migrate any data, only dump DDL statements. Output DDL statements for table creation, indexes, auto increment columns, views, and other objects to createSql.log in the log file
258+
259+
OracleSync2MySQL.exe --config file.yml -m
260+
261+
```
262+
e.g.
263+
OracleSync2MySQL.exe --config example.yml -m
264+
```
265+
255266
## change history
267+
### v0.1.3
268+
2024-06-04
269+
fix tablemeta view problem,add -m mode only output ddl script to plat file
270+
271+
272+
### v0.1.2
273+
2024-05-30
274+
fix missing default value
275+
276+
### v0.1.1
277+
2024-05-14
278+
add column comment
279+
256280
### v0.1.0
257281
2024-03-29
258282
fix some error

readme_cn.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,32 @@ OracleSync2MySQL.exe --config 配置文件 onlyData -s
240240
OracleSync2MySQL.exe --config example.yml onlyData -s
241241
```
242242

243+
### 3.7 输出建库脚本
244+
245+
不迁移任何数据,仅转储DDL语句,表创建、索引、自增列、视图等对象ddl语句输出到log文件下的createSql.log
246+
247+
OracleSync2MySQL.exe --config 配置文件 -m
248+
249+
```
250+
示例
251+
OracleSync2MySQL.exe --config example.yml -m
252+
```
253+
243254
## change history
255+
### v0.1.3
256+
2024-06-04
257+
修复tablemeta中视图批量替换的问题,新增-m模式,仅输出创建数据库对象的脚本文件到createSql.log文件,不会迁移任何对象
258+
259+
260+
### v0.1.2
261+
2024-05-30
262+
修复默认值缺失的问题
263+
264+
### v0.1.1
265+
2024-05-14
266+
修复注释没有迁移的问题
267+
268+
244269
### v0.1.0
245270
2024-03-29
246271
修复分页查询遇到别名冲突问题

0 commit comments

Comments
 (0)