github.com/xiyichan/dm8@v0.0.0-20211213021639-be727be3e136/zf.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 rwFilter struct {
    15  }
    16  
    17  //DmDriver
    18  func (rwf *rwFilter) DmDriverOpen(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnection, error) {
    19  	return filterChain.DmDriverOpen(d, dsn)
    20  }
    21  
    22  func (rwf *rwFilter) DmDriverOpenConnector(filterChain *filterChain, d *DmDriver, dsn string) (*DmConnector, error) {
    23  	return filterChain.DmDriverOpenConnector(d, dsn)
    24  }
    25  
    26  //DmConnector
    27  func (rwf *rwFilter) DmConnectorConnect(filterChain *filterChain, c *DmConnector, ctx context.Context) (*DmConnection, error) {
    28  	connection, err := filterChain.DmConnectorConnect(c, ctx)
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	// printPrimary(connection);
    33  	connection.rwInfo.rwCounter = getRwCounterInstance(connection) // rwCounter放在连接上,不用每次都要从map中获取
    34  	RWUtil.connectStandby(connection)
    35  	// printStandby(connection);
    36  	return connection, nil
    37  }
    38  
    39  func (rwf *rwFilter) DmConnectorDriver(filterChain *filterChain, c *DmConnector) *DmDriver {
    40  	return filterChain.DmConnectorDriver(c)
    41  }
    42  
    43  //DmConnection
    44  func (rwf *rwFilter) DmConnectionBegin(filterChain *filterChain, c *DmConnection) (*DmConnection, error) {
    45  	if RWUtil.isStandbyAlive(c) {
    46  		_, err := c.rwInfo.connStandby.begin()
    47  		if err != nil {
    48  			RWUtil.afterExceptionOnStandby(c, err)
    49  		}
    50  	}
    51  
    52  	return filterChain.DmConnectionBegin(c)
    53  }
    54  
    55  func (rwf *rwFilter) DmConnectionBeginTx(filterChain *filterChain, c *DmConnection, ctx context.Context, opts driver.TxOptions) (*DmConnection, error) {
    56  	if RWUtil.isStandbyAlive(c) {
    57  		_, err := c.rwInfo.connStandby.beginTx(ctx, opts)
    58  		if err != nil {
    59  			RWUtil.afterExceptionOnStandby(c, err)
    60  		}
    61  	}
    62  
    63  	return filterChain.DmConnectionBeginTx(c, ctx, opts)
    64  }
    65  
    66  func (rwf *rwFilter) DmConnectionCommit(filterChain *filterChain, c *DmConnection) error {
    67  	if RWUtil.isStandbyAlive(c) {
    68  		err := c.rwInfo.connStandby.commit()
    69  		if err != nil {
    70  			RWUtil.afterExceptionOnStandby(c, err)
    71  		}
    72  	}
    73  
    74  	return filterChain.DmConnectionCommit(c)
    75  }
    76  
    77  func (rwf *rwFilter) DmConnectionRollback(filterChain *filterChain, c *DmConnection) error {
    78  	if RWUtil.isStandbyAlive(c) {
    79  		err := c.rwInfo.connStandby.rollback()
    80  		if err != nil {
    81  			RWUtil.afterExceptionOnStandby(c, err)
    82  		}
    83  	}
    84  
    85  	return filterChain.DmConnectionRollback(c)
    86  }
    87  
    88  func (rwf *rwFilter) DmConnectionClose(filterChain *filterChain, c *DmConnection) error {
    89  	if RWUtil.isStandbyAlive(c) {
    90  		err := c.rwInfo.connStandby.close()
    91  		if err != nil {
    92  			RWUtil.afterExceptionOnStandby(c, err)
    93  		}
    94  	}
    95  
    96  	return filterChain.DmConnectionClose(c)
    97  }
    98  
    99  func (rwf *rwFilter) DmConnectionPing(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
   100  	return filterChain.DmConnectionPing(c, ctx)
   101  }
   102  
   103  func (rwf *rwFilter) DmConnectionExec(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmResult, error) {
   104  	ret, err := RWUtil.executeByConn(c, func() (interface{}, error) {
   105  		RWUtil.distributeSqlByConn(c, query)
   106  		return c.rwInfo.connCurrent.exec(query, args)
   107  	}, func(otherConn *DmConnection) (interface{}, error) {
   108  		return otherConn.exec(query, args)
   109  	})
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	return ret.(*DmResult), nil
   114  }
   115  
   116  func (rwf *rwFilter) DmConnectionExecContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmResult, error) {
   117  	ret, err := RWUtil.executeByConn(c, func() (interface{}, error) {
   118  		RWUtil.distributeSqlByConn(c, query)
   119  		return c.rwInfo.connCurrent.execContext(ctx, query, args)
   120  	}, func(otherConn *DmConnection) (interface{}, error) {
   121  		return otherConn.execContext(ctx, query, args)
   122  	})
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	return ret.(*DmResult), nil
   127  }
   128  
   129  func (rwf *rwFilter) DmConnectionQuery(filterChain *filterChain, c *DmConnection, query string, args []driver.Value) (*DmRows, error) {
   130  	ret, err := RWUtil.executeByConn(c, func() (interface{}, error) {
   131  		RWUtil.distributeSqlByConn(c, query)
   132  		return c.rwInfo.connCurrent.query(query, args)
   133  	}, func(otherConn *DmConnection) (interface{}, error) {
   134  		return otherConn.query(query, args)
   135  	})
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	return ret.(*DmRows), nil
   140  }
   141  
   142  func (rwf *rwFilter) DmConnectionQueryContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string, args []driver.NamedValue) (*DmRows, error) {
   143  	ret, err := RWUtil.executeByConn(c, func() (interface{}, error) {
   144  		RWUtil.distributeSqlByConn(c, query)
   145  		return c.rwInfo.connCurrent.queryContext(ctx, query, args)
   146  	}, func(otherConn *DmConnection) (interface{}, error) {
   147  		return otherConn.queryContext(ctx, query, args)
   148  	})
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  	return ret.(*DmRows), nil
   153  }
   154  
   155  func (rwf *rwFilter) DmConnectionPrepare(filterChain *filterChain, c *DmConnection, query string) (*DmStatement, error) {
   156  	distribute := RWUtil.distributeSqlByConn(c, query)
   157  	stmt, err := filterChain.DmConnectionPrepare(c, query)
   158  	if err != nil {
   159  		return nil, err
   160  	}
   161  	stmt.rwInfo.stmtCurrent = stmt
   162  	if stmt != nil && distribute == STANDBY {
   163  		stmt.rwInfo.stmtStandby, err = c.rwInfo.connStandby.prepare(query)
   164  		if err != nil {
   165  			RWUtil.afterExceptionOnStandby(c, err)
   166  		}
   167  		stmt.rwInfo.stmtCurrent = stmt.rwInfo.stmtStandby
   168  	}
   169  
   170  	return stmt, nil
   171  }
   172  
   173  func (rwf *rwFilter) DmConnectionPrepareContext(filterChain *filterChain, c *DmConnection, ctx context.Context, query string) (*DmStatement, error) {
   174  	distribute := RWUtil.distributeSqlByConn(c, query)
   175  	stmt, err := filterChain.DmConnectionPrepareContext(c, ctx, query)
   176  	if err != nil {
   177  		return nil, err
   178  	}
   179  	stmt.rwInfo.stmtCurrent = stmt
   180  	if stmt != nil && distribute == STANDBY {
   181  		stmt.rwInfo.stmtStandby, err = c.rwInfo.connStandby.prepareContext(ctx, query)
   182  		if err != nil {
   183  			RWUtil.afterExceptionOnStandby(c, err)
   184  		}
   185  		stmt.rwInfo.stmtCurrent = stmt.rwInfo.stmtStandby
   186  	}
   187  
   188  	return stmt, nil
   189  }
   190  
   191  func (rwf *rwFilter) DmConnectionResetSession(filterChain *filterChain, c *DmConnection, ctx context.Context) error {
   192  	if RWUtil.isStandbyAlive(c) {
   193  		err := c.rwInfo.connStandby.resetSession(ctx)
   194  		if err != nil {
   195  			RWUtil.afterExceptionOnStandby(c, err)
   196  		}
   197  	}
   198  
   199  	return filterChain.DmConnectionResetSession(c, ctx)
   200  }
   201  
   202  func (rwf *rwFilter) DmConnectionCheckNamedValue(filterChain *filterChain, c *DmConnection, nv *driver.NamedValue) error {
   203  	return filterChain.DmConnectionCheckNamedValue(c, nv)
   204  }
   205  
   206  //DmStatement
   207  func (rwf *rwFilter) DmStatementClose(filterChain *filterChain, s *DmStatement) error {
   208  	if RWUtil.isStandbyStatementValid(s) {
   209  		err := s.rwInfo.stmtStandby.close()
   210  		if err != nil {
   211  			RWUtil.afterExceptionOnStandby(s.dmConn, err)
   212  		}
   213  	}
   214  
   215  	return filterChain.DmStatementClose(s)
   216  }
   217  
   218  func (rwf *rwFilter) DmStatementNumInput(filterChain *filterChain, s *DmStatement) int {
   219  	return filterChain.DmStatementNumInput(s)
   220  }
   221  
   222  func (rwf *rwFilter) DmStatementExec(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmResult, error) {
   223  	ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
   224  		RWUtil.distributeSqlByStmt(s, s.nativeSql)
   225  		return s.rwInfo.stmtCurrent.exec(args)
   226  	}, func(otherStmt *DmStatement) (interface{}, error) {
   227  		return otherStmt.exec(args)
   228  	})
   229  	if err != nil {
   230  		return nil, err
   231  	}
   232  	return ret.(*DmResult), nil
   233  }
   234  
   235  func (rwf *rwFilter) DmStatementExecContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmResult, error) {
   236  	ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
   237  		RWUtil.distributeSqlByStmt(s, s.nativeSql)
   238  		return s.rwInfo.stmtCurrent.execContext(ctx, args)
   239  	}, func(otherStmt *DmStatement) (interface{}, error) {
   240  		return otherStmt.execContext(ctx, args)
   241  	})
   242  	if err != nil {
   243  		return nil, err
   244  	}
   245  	return ret.(*DmResult), nil
   246  }
   247  
   248  func (rwf *rwFilter) DmStatementQuery(filterChain *filterChain, s *DmStatement, args []driver.Value) (*DmRows, error) {
   249  	ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
   250  		RWUtil.distributeSqlByStmt(s, s.nativeSql)
   251  		return s.rwInfo.stmtCurrent.query(args)
   252  	}, func(otherStmt *DmStatement) (interface{}, error) {
   253  		return otherStmt.query(args)
   254  	})
   255  	if err != nil {
   256  		return nil, err
   257  	}
   258  	return ret.(*DmRows), nil
   259  }
   260  
   261  func (rwf *rwFilter) DmStatementQueryContext(filterChain *filterChain, s *DmStatement, ctx context.Context, args []driver.NamedValue) (*DmRows, error) {
   262  	ret, err := RWUtil.executeByStmt(s, func() (interface{}, error) {
   263  		RWUtil.distributeSqlByStmt(s, s.nativeSql)
   264  		return s.rwInfo.stmtCurrent.queryContext(ctx, args)
   265  	}, func(otherStmt *DmStatement) (interface{}, error) {
   266  		return otherStmt.queryContext(ctx, args)
   267  	})
   268  	if err != nil {
   269  		return nil, err
   270  	}
   271  	return ret.(*DmRows), nil
   272  }
   273  
   274  func (rwf *rwFilter) DmStatementCheckNamedValue(filterChain *filterChain, s *DmStatement, nv *driver.NamedValue) error {
   275  	return filterChain.DmStatementCheckNamedValue(s, nv)
   276  }
   277  
   278  //DmResult
   279  func (rwf *rwFilter) DmResultLastInsertId(filterChain *filterChain, r *DmResult) (int64, error) {
   280  	return filterChain.DmResultLastInsertId(r)
   281  }
   282  
   283  func (rwf *rwFilter) DmResultRowsAffected(filterChain *filterChain, r *DmResult) (int64, error) {
   284  	return filterChain.DmResultRowsAffected(r)
   285  }
   286  
   287  //DmRows
   288  func (rwf *rwFilter) DmRowsColumns(filterChain *filterChain, r *DmRows) []string {
   289  	return filterChain.DmRowsColumns(r)
   290  }
   291  
   292  func (rwf *rwFilter) DmRowsClose(filterChain *filterChain, r *DmRows) error {
   293  	return filterChain.DmRowsClose(r)
   294  }
   295  
   296  func (rwf *rwFilter) DmRowsNext(filterChain *filterChain, r *DmRows, dest []driver.Value) error {
   297  	return filterChain.DmRowsNext(r, dest)
   298  }
   299  
   300  func (rwf *rwFilter) DmRowsHasNextResultSet(filterChain *filterChain, r *DmRows) bool {
   301  	return filterChain.DmRowsHasNextResultSet(r)
   302  }
   303  
   304  func (rwf *rwFilter) DmRowsNextResultSet(filterChain *filterChain, r *DmRows) error {
   305  	return filterChain.DmRowsNextResultSet(r)
   306  }
   307  
   308  func (rwf *rwFilter) DmRowsColumnTypeScanType(filterChain *filterChain, r *DmRows, index int) reflect.Type {
   309  	return filterChain.DmRowsColumnTypeScanType(r, index)
   310  }
   311  
   312  func (rwf *rwFilter) DmRowsColumnTypeDatabaseTypeName(filterChain *filterChain, r *DmRows, index int) string {
   313  	return filterChain.DmRowsColumnTypeDatabaseTypeName(r, index)
   314  }
   315  
   316  func (rwf *rwFilter) DmRowsColumnTypeLength(filterChain *filterChain, r *DmRows, index int) (length int64, ok bool) {
   317  	return filterChain.DmRowsColumnTypeLength(r, index)
   318  }
   319  
   320  func (rwf *rwFilter) DmRowsColumnTypeNullable(filterChain *filterChain, r *DmRows, index int) (nullable, ok bool) {
   321  	return filterChain.DmRowsColumnTypeNullable(r, index)
   322  }
   323  
   324  func (rwf *rwFilter) DmRowsColumnTypePrecisionScale(filterChain *filterChain, r *DmRows, index int) (precision, scale int64, ok bool) {
   325  	return filterChain.DmRowsColumnTypePrecisionScale(r, index)
   326  }