github.com/xiyichan/dm8@v0.0.0-20211213021639-be727be3e136/ze.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 6 package dm 7 8 import ( 9 "context" 10 "database/sql/driver" 11 "reflect" 12 ) 13 14 type reconnectFilter struct { 15 } 16 17 func (rf *reconnectFilter) autoReconnect(connection *DmConnection, err error) error { 18 if dmErr, ok := err.(*DmError); ok { 19 if dmErr.ErrCode == ECGO_COMMUNITION_ERROR.ErrCode { 20 return rf.reconnect(connection, dmErr.Error()) 21 } 22 } 23 return err 24 } 25 26 func (rf *reconnectFilter) reconnect(connection *DmConnection, reason string) error { 27 // 读写分离,重连需要处理备机 28 var err error 29 if connection.dmConnector.rwSeparate { 30 err = RWUtil.reconnect(connection) 31 } else { 32 err = connection.reconnect() 33 } 34 35 if err != nil { 36 return ECGO_CONNECTION_SWITCH_FAILED.throw() 37 } 38 39 // 重连成功 40 return ECGO_CONNECTION_SWITCHED.throw() 41 } 42 43 //DmDriver 44 func (rf *reconnectFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnection, error) { 45 return filterChain.DmDriverOpen(d, dsn) 46 } 47 48 func (rf *reconnectFilter) DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnector, error) { 49 return filterChain.DmDriverOpenConnector(d, dsn) 50 } 51 52 //DmConnector 53 func (rf *reconnectFilter) DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (*DmConnection, error) { 54 return filterChain.DmConnectorConnect(c, ctx) 55 } 56 57 func (rf *reconnectFilter) DmConnectorDriver(filterChain *filterChain, c *DmConnector) *DmDriver { 58 return filterChain.DmConnectorDriver(c) 59 } 60 61 //DmConnection 62 func (rf *reconnectFilter) DmConnectionBegin(filterChain *filterChain, c *DmConnection) (*DmConnection, error) { 63 dc, err := filterChain.DmConnectionBegin(c) 64 if err != nil { 65 err = rf.autoReconnect(c, err) 66 return nil, err 67 } 68 return dc, err 69 } 70 71 func (rf *reconnectFilter) DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error) { 72 dc, err := filterChain.DmConnectionBeginTx(c, ctx, opts) 73 if err != nil { 74 err = rf.autoReconnect(c, err) 75 return nil, err 76 } 77 return dc, err 78 } 79 80 func (rf *reconnectFilter) DmConnectionCommit(filterChain *filterChain, c *DmConnection) error { 81 err := filterChain.DmConnectionCommit(c) 82 if err != nil { 83 err = rf.autoReconnect(c, err) 84 } 85 86 return err 87 } 88 89 func (rf *reconnectFilter) DmConnectionRollback(filterChain *filterChain, c *DmConnection) error { 90 err := filterChain.DmConnectionRollback(c) 91 if err != nil { 92 err = rf.autoReconnect(c, err) 93 } 94 95 return err 96 } 97 98 func (rf *reconnectFilter) DmConnectionClose(filterChain *filterChain, c *DmConnection) error { 99 err := filterChain.DmConnectionClose(c) 100 if err != nil { 101 err = rf.autoReconnect(c, err) 102 } 103 104 return err 105 } 106 107 func (rf *reconnectFilter) DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) error { 108 err := filterChain.DmConnectionPing(c, ctx) 109 if err != nil { 110 err = rf.autoReconnect(c, err) 111 } 112 113 return err 114 } 115 116 func (rf *reconnectFilter) DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmResult, error) { 117 dr, err := filterChain.DmConnectionExec(c, query, args) 118 if err != nil { 119 err = rf.autoReconnect(c, err) 120 return nil, err 121 } 122 123 return dr, err 124 } 125 126 func (rf *reconnectFilter) DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) { 127 dr, err := filterChain.DmConnectionExecContext(c, ctx, query, args) 128 if err != nil { 129 err = rf.autoReconnect(c, err) 130 return nil, err 131 } 132 133 return dr, err 134 } 135 136 func (rf *reconnectFilter) DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmRows, error) { 137 dr, err := filterChain.DmConnectionQuery(c, query, args) 138 if err != nil { 139 err = rf.autoReconnect(c, err) 140 return nil, err 141 } 142 143 return dr, err 144 } 145 146 func (rf *reconnectFilter) DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) { 147 dr, err := filterChain.DmConnectionQueryContext(c, ctx, query, args) 148 if err != nil { 149 err = rf.autoReconnect(c, err) 150 return nil, err 151 } 152 153 return dr, err 154 } 155 156 func (rf *reconnectFilter) DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (*DmStatement, error) { 157 ds, err := filterChain.DmConnectionPrepare(c, query) 158 if err != nil { 159 err = rf.autoReconnect(c, err) 160 return nil, err 161 } 162 163 return ds, err 164 } 165 166 func (rf *reconnectFilter) DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (*DmStatement, error) { 167 ds, err := filterChain.DmConnectionPrepareContext(c, ctx, query) 168 if err != nil { 169 err = rf.autoReconnect(c, err) 170 return nil, err 171 } 172 173 return ds, err 174 } 175 176 func (rf *reconnectFilter) DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) error { 177 err := filterChain.DmConnectionResetSession(c, ctx) 178 if err != nil { 179 err = rf.autoReconnect(c, err) 180 } 181 182 return err 183 } 184 185 func (rf *reconnectFilter) DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) error { 186 err := filterChain.DmConnectionCheckNamedValue(c, nv) 187 if err != nil { 188 err = rf.autoReconnect(c, err) 189 } 190 191 return err 192 } 193 194 //DmStatement 195 func (rf *reconnectFilter) DmStatementClose(filterChain *filterChain, s *DmStatement) error { 196 err := filterChain.DmStatementClose(s) 197 if err != nil { 198 err = rf.autoReconnect(s.dmConn, err) 199 } 200 201 return err 202 } 203 204 func (rf *reconnectFilter) DmStatementNumInput(filterChain *filterChain, s *DmStatement) int { 205 var ret int 206 defer func() { 207 err := recover() 208 if err != nil { 209 rf.autoReconnect(s.dmConn, err.(error)) 210 ret = 0 211 } 212 }() 213 ret = filterChain.DmStatementNumInput(s) 214 return ret 215 } 216 217 func (rf *reconnectFilter) DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmResult, error) { 218 dr, err := filterChain.DmStatementExec(s, args) 219 if err != nil { 220 err = rf.autoReconnect(s.dmConn, err) 221 return nil, err 222 } 223 224 return dr, err 225 } 226 227 func (rf *reconnectFilter) DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error) { 228 dr, err := filterChain.DmStatementExecContext(s, ctx, args) 229 if err != nil { 230 err = rf.autoReconnect(s.dmConn, err) 231 return nil, err 232 } 233 234 return dr, err 235 } 236 237 func (rf *reconnectFilter) DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmRows, error) { 238 dr, err := filterChain.DmStatementQuery(s, args) 239 if err != nil { 240 err = rf.autoReconnect(s.dmConn, err) 241 return nil, err 242 } 243 244 return dr, err 245 } 246 247 func (rf *reconnectFilter) DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error) { 248 dr, err := filterChain.DmStatementQueryContext(s, ctx, args) 249 if err != nil { 250 err = rf.autoReconnect(s.dmConn, err) 251 return nil, err 252 } 253 254 return dr, err 255 } 256 257 func (rf *reconnectFilter) DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) error { 258 err := filterChain.DmStatementCheckNamedValue(s, nv) 259 if err != nil { 260 err = rf.autoReconnect(s.dmConn, err) 261 } 262 263 return err 264 } 265 266 //DmResult 267 func (rf *reconnectFilter) DmResultLastInsertId(filterChain *filterChain, r *DmResult) (int64, error) { 268 i, err := filterChain.DmResultLastInsertId(r) 269 if err != nil { 270 err = rf.autoReconnect(r.dmStmt.dmConn, err) 271 return 0, err 272 } 273 274 return i, err 275 } 276 277 func (rf *reconnectFilter) DmResultRowsAffected(filterChain *filterChain, r *DmResult) (int64, error) { 278 i, err := filterChain.DmResultRowsAffected(r) 279 if err != nil { 280 err = rf.autoReconnect(r.dmStmt.dmConn, err) 281 return 0, err 282 } 283 284 return i, err 285 } 286 287 //DmRows 288 func (rf *reconnectFilter) DmRowsColumns(filterChain *filterChain, r *DmRows) []string { 289 var ret []string 290 defer func() { 291 err := recover() 292 if err != nil { 293 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 294 ret = nil 295 } 296 }() 297 ret = filterChain.DmRowsColumns(r) 298 return ret 299 } 300 301 func (rf *reconnectFilter) DmRowsClose(filterChain *filterChain, r *DmRows) error { 302 err := filterChain.DmRowsClose(r) 303 if err != nil { 304 err = rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err) 305 } 306 307 return err 308 } 309 310 func (rf *reconnectFilter) DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) error { 311 err := filterChain.DmRowsNext(r, dest) 312 if err != nil { 313 err = rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err) 314 } 315 316 return err 317 } 318 319 func (rf *reconnectFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) bool { 320 var ret bool 321 defer func() { 322 err := recover() 323 if err != nil { 324 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 325 ret = false 326 } 327 }() 328 ret = filterChain.DmRowsHasNextResultSet(r) 329 return ret 330 } 331 332 func (rf *reconnectFilter) DmRowsNextResultSet(filterChain *filterChain, r *DmRows) error { 333 err := filterChain.DmRowsNextResultSet(r) 334 if err != nil { 335 err = rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err) 336 } 337 338 return err 339 } 340 341 func (rf *reconnectFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) reflect.Type { 342 var ret reflect.Type 343 defer func() { 344 err := recover() 345 if err != nil { 346 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 347 ret = scanTypeUnknown 348 } 349 }() 350 ret = filterChain.DmRowsColumnTypeScanType(r, index) 351 return ret 352 } 353 354 func (rf *reconnectFilter) DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) string { 355 var ret string 356 defer func() { 357 err := recover() 358 if err != nil { 359 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 360 ret = "" 361 } 362 }() 363 ret = filterChain.DmRowsColumnTypeDatabaseTypeName(r, index) 364 return ret 365 } 366 367 func (rf *reconnectFilter) DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool) { 368 defer func() { 369 err := recover() 370 if err != nil { 371 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 372 length, ok = 0, false 373 } 374 }() 375 return filterChain.DmRowsColumnTypeLength(r, index) 376 } 377 378 func (rf *reconnectFilter) DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool) { 379 defer func() { 380 err := recover() 381 if err != nil { 382 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 383 nullable, ok = false, false 384 } 385 }() 386 return filterChain.DmRowsColumnTypeNullable(r, index) 387 } 388 389 func (rf *reconnectFilter) DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool) { 390 defer func() { 391 err := recover() 392 if err != nil { 393 rf.autoReconnect(r.CurrentRows.dmStmt.dmConn, err.(error)) 394 precision, scale, ok = 0, 0, false 395 } 396 }() 397 return filterChain.DmRowsColumnTypePrecisionScale(r, index) 398 }