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  }