zhangqian
2023-10-09 41a9bf370cff977ff8afe122a7610e07fa6c3b80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package serf
 
import (
    "errors"
    "fmt"
    "regexp"
    "strings"
 
    "github.com/jinzhu/gorm"
)
 
type DumpSql struct {
    Sql string `json:"sql"`
}
 
type TableDesc struct {
    Cid       int         `json:"cid"`
    Name      string      `json:"name"`
    Type      string      `json:"type"`
    Notnull   bool        `json:"notnull"`
    DFltValue interface{} `json:"dflt_value"`
    Pk        int         `json:"pk"`
}
 
var syncSqlChan = make(chan string, 10)
 
func DumpTables(db *gorm.DB, tableNames []string) ([]string, error) {
    db.LogMode(false)
    defer db.LogMode(true)
 
    if tableNames != nil {
        var arr []string
        var dumpSql []DumpSql
 
        for _, table := range tableNames {
            fmt.Println("dump current tableName:", table)
 
            dumpSql = make([]DumpSql, 0)
            var tDescArr []TableDesc
 
            tSql := fmt.Sprintf(`PRAGMA table_info("%s")`, table)
            err := db.Raw(tSql).Scan(&tDescArr).Error
 
            fmt.Println("tDescArr err:", err, "len(tDescArr)=", len(tDescArr))
            if err != nil {
                return nil, errors.New("tableDesc err")
            }
 
            fmt.Println(table, "'Columns is:", tDescArr)
            if tDescArr == nil || len(tDescArr) == 0 {
                return nil, errors.New(table + " has no column")
            }
 
            var columnNames []string
            for _, col := range tDescArr {
                columnNames = append(columnNames, fmt.Sprintf(`'||quote("%s")||'`, col.Name))
            }
 
            tSql = fmt.Sprintf(`SELECT 'INSERT INTO "%s" VALUES(%s)' as sql FROM "%s";`,
                table,
                strings.Join(columnNames, ","),
                table)
            //fmt.Println("tSql:", tSql)
 
            err = db.Raw(tSql).Scan(&dumpSql).Error
            if err != nil {
                return nil, errors.New("dump err")
            }
 
            if len(dumpSql) > 0 {
                for _, d := range dumpSql {
                    arr = append(arr, d.Sql)
                }
            }
        }
 
        return arr, nil
    }
 
    return nil, errors.New("tableNames is nil")
}
 
type DbLogger struct {
}
 
func (dbLogger *DbLogger) Print(values ...interface{}) {
    var (
        level = values[0]
    )
 
    fmt.Println("dblogger", values)
 
    if level == "sql" {
        msgArr := gorm.LogFormatter(values...)
        sql := msgArr[3].(string)
        sql = strings.TrimPrefix(sql, " ")
        if !strings.HasPrefix(sql, "SELECT") && !strings.HasPrefix(sql, "select") && !strings.Contains(sql, "PRAGMA") && !strings.Contains(sql, "pragma") {
            affected := values[5].(int64)
            if affected > 0 { //执行成功
                //判断操作的是哪张表
                whereIdx := strings.Index(sql, "WHERE")
                sqlWithTable := sql
                if whereIdx > -1 {
                    sqlWithTable = sql[:whereIdx]
                }
 
                fmt.Println("判断是哪张表 sqlWithTable:", sqlWithTable)
 
                insertReg := regexp.MustCompile(`^\s*(?i:insert)\s`) //insert
                updateReg := regexp.MustCompile(`^\s*(?i:update)\s`) //update
                delReg := regexp.MustCompile(`^\s*(?i:delete)\s`)    //delete
 
                if insertReg.MatchString(sqlWithTable) {
                    fmt.Println("插入操作")
                    for _, t := range agent.syncTables {
                        reg := regexp.MustCompile(`\s+\"?(?i:` + t + `)\"?\s+`)
                        if reg.MatchString(sqlWithTable) {
                            fmt.Println("属于同步表:", t)
                            syncSqlChan <- sql
                        }
                    }
                } else if updateReg.MatchString(sqlWithTable) || delReg.MatchString(sqlWithTable) {
                    fmt.Println("删除或者更新")
                    for _, t := range agent.syncTables {
                        reg := regexp.MustCompile(`\s+\"?(?i:` + t + `)\"?\s+`)
                        if reg.MatchString(sqlWithTable) {
                            fmt.Println("属于同步表:", t)
                            syncSqlChan <- sql
                        }
                    }
                }
            }
        }
    } else {
        fmt.Println("dbLogger level!=sql")
    }
}