| 74 | } |
| 75 | |
| 76 | func Exec(sql string) (*mysql.Result, error) { |
| 77 | prefix := sql |
| 78 | if len(sql) > 20 { |
| 79 | prefix = sql[:20] |
| 80 | } |
| 81 | prefix = strings.ToUpper(prefix) |
| 82 | for _, v := range DMLSQL { |
| 83 | if strings.HasPrefix(prefix, v) { |
| 84 | result, err := db.Exec(sql) |
| 85 | if err != nil { |
| 86 | return nil, err |
| 87 | } |
| 88 | if config.Get().P2P.Enable { |
| 89 | p2pPubSub.Outbound <- sql |
| 90 | logrus.Infof("Outbound sql: %s", sql) |
| 91 | } |
| 92 | |
| 93 | rf, _ := result.RowsAffected() |
| 94 | li, _ := result.LastInsertId() |
| 95 | res := &mysql.Result{ |
| 96 | Status: 2, |
| 97 | Warnings: 0, |
| 98 | InsertId: uint64(li), |
| 99 | AffectedRows: uint64(rf), |
| 100 | } |
| 101 | return res, nil |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | resp, err := db.Query(sql, nil) |
| 106 | if err != nil { |
| 107 | return nil, err |
| 108 | } |
| 109 | |
| 110 | column, err := resp.Columns() |
| 111 | if err != nil { |
| 112 | return nil, err |
| 113 | } |
| 114 | columnType, err := resp.ColumnTypes() |
| 115 | if err != nil { |
| 116 | return nil, err |
| 117 | } |
| 118 | res := &mysql.Result{ |
| 119 | Resultset: mysql.NewResultset(len(column)), |
| 120 | } |
| 121 | res.Status = 31 |
| 122 | // writer Fields |
| 123 | tableName := []byte(getTableName(sql)) |
| 124 | for k, v := range column { |
| 125 | f := &mysql.Field{} |
| 126 | f.Name = []byte(v) |
| 127 | f.Schema = tableName |
| 128 | f.Table = tableName |
| 129 | f.OrgTable = tableName |
| 130 | f.OrgName = tableName |
| 131 | f.Charset = 33 // utf8 |
| 132 | // https://dev.mysql.com/doc/internals/en/com-query-response.html#column-type |
| 133 | f.Type, f.ColumnLength = getColumnTypeAndLen(columnType[k].DatabaseTypeName()) |