github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/sessionctx/variable/session.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package variable
    15  
    16  import (
    17  	"github.com/insionng/yougam/libraries/pingcap/tidb/context"
    18  	"github.com/insionng/yougam/libraries/pingcap/tidb/terror"
    19  )
    20  
    21  const codeCantGetValidID terror.ErrCode = 1
    22  
    23  var errCantGetValidID = terror.ClassVariable.New(codeCantGetValidID, "cannot get valid auto-increment id in retry")
    24  
    25  // RetryInfo saves retry information.
    26  type RetryInfo struct {
    27  	Retrying         bool
    28  	currRetryOff     int
    29  	autoIncrementIDs []int64
    30  }
    31  
    32  // Clean does some clean work.
    33  func (r *RetryInfo) Clean() {
    34  	r.currRetryOff = 0
    35  	if len(r.autoIncrementIDs) > 0 {
    36  		r.autoIncrementIDs = r.autoIncrementIDs[:0]
    37  	}
    38  }
    39  
    40  // AddAutoIncrementID adds id to AutoIncrementIDs.
    41  func (r *RetryInfo) AddAutoIncrementID(id int64) {
    42  	r.autoIncrementIDs = append(r.autoIncrementIDs, id)
    43  }
    44  
    45  // ResetOffset resets the current retry offset.
    46  func (r *RetryInfo) ResetOffset() {
    47  	r.currRetryOff = 0
    48  }
    49  
    50  // GetCurrAutoIncrementID gets current AutoIncrementID.
    51  func (r *RetryInfo) GetCurrAutoIncrementID() (int64, error) {
    52  	if r.currRetryOff >= len(r.autoIncrementIDs) {
    53  		return 0, errCantGetValidID
    54  	}
    55  	id := r.autoIncrementIDs[r.currRetryOff]
    56  	r.currRetryOff++
    57  
    58  	return id, nil
    59  }
    60  
    61  // SessionVars is to handle user-defined or global variables in current session.
    62  type SessionVars struct {
    63  	// user-defined variables
    64  	Users map[string]string
    65  	// system variables
    66  	Systems map[string]string
    67  	// prepared statement
    68  	PreparedStmts        map[uint32]interface{}
    69  	PreparedStmtNameToID map[string]uint32
    70  	// prepared statement auto increment id
    71  	preparedStmtID uint32
    72  
    73  	// retry information
    74  	RetryInfo *RetryInfo
    75  
    76  	// following variables are special for current session
    77  	Status       uint16
    78  	LastInsertID uint64
    79  	AffectedRows uint64
    80  
    81  	// Client capability
    82  	ClientCapability uint32
    83  
    84  	// Connection ID
    85  	ConnectionID uint64
    86  
    87  	// Found rows
    88  	FoundRows uint64
    89  
    90  	// Current user
    91  	User string
    92  }
    93  
    94  // sessionVarsKeyType is a dummy type to avoid naming collision in context.
    95  type sessionVarsKeyType int
    96  
    97  // String defines a Stringer function for debugging and pretty printing.
    98  func (k sessionVarsKeyType) String() string {
    99  	return "session_vars"
   100  }
   101  
   102  const sessionVarsKey sessionVarsKeyType = 0
   103  
   104  // BindSessionVars creates a session vars object and binds it to context.
   105  func BindSessionVars(ctx context.Context) {
   106  	v := &SessionVars{
   107  		Users:                make(map[string]string),
   108  		Systems:              make(map[string]string),
   109  		PreparedStmts:        make(map[uint32]interface{}),
   110  		PreparedStmtNameToID: make(map[string]uint32),
   111  		RetryInfo:            &RetryInfo{},
   112  	}
   113  
   114  	ctx.SetValue(sessionVarsKey, v)
   115  }
   116  
   117  // GetSessionVars gets the session vars from context.
   118  func GetSessionVars(ctx context.Context) *SessionVars {
   119  	v, ok := ctx.Value(sessionVarsKey).(*SessionVars)
   120  	if !ok {
   121  		return nil
   122  	}
   123  	return v
   124  }
   125  
   126  const (
   127  	characterSetConnection = "character_set_connection"
   128  	collationConnection    = "collation_connection"
   129  )
   130  
   131  // GetCharsetInfo gets charset and collation for current context.
   132  // What character set should the server translate a statement to after receiving it?
   133  // For this, the server uses the character_set_connection and collation_connection system variables.
   134  // It converts statements sent by the client from character_set_client to character_set_connection
   135  // (except for string literals that have an introducer such as _latin1 or _utf8).
   136  // collation_connection is important for comparisons of literal strings.
   137  // For comparisons of strings with column values, collation_connection does not matter because columns
   138  // have their own collation, which has a higher collation precedence.
   139  // See: https://dev.mysql.com/doc/refman/5.7/en/charset-connection.html
   140  func GetCharsetInfo(ctx context.Context) (charset, collation string) {
   141  	sessionVars := GetSessionVars(ctx)
   142  	charset = sessionVars.Systems[characterSetConnection]
   143  	collation = sessionVars.Systems[collationConnection]
   144  	return
   145  }
   146  
   147  // SetLastInsertID saves the last insert id to the session context.
   148  // TODO: we may store the result for last_insert_id sys var later.
   149  func (s *SessionVars) SetLastInsertID(insertID uint64) {
   150  	s.LastInsertID = insertID
   151  }
   152  
   153  // SetAffectedRows saves the affected rows to the session context.
   154  func (s *SessionVars) SetAffectedRows(affectedRows uint64) {
   155  	s.AffectedRows = affectedRows
   156  }
   157  
   158  // AddAffectedRows adds affected rows with the argument rows.
   159  func (s *SessionVars) AddAffectedRows(rows uint64) {
   160  	s.AffectedRows += rows
   161  }
   162  
   163  // AddFoundRows adds found rows with the argument rows.
   164  func (s *SessionVars) AddFoundRows(rows uint64) {
   165  	s.FoundRows += rows
   166  }
   167  
   168  // SetStatusFlag sets the session server status variable.
   169  // If on is ture sets the flag in session status,
   170  // otherwise removes the flag.
   171  func (s *SessionVars) SetStatusFlag(flag uint16, on bool) {
   172  	if on {
   173  		s.Status |= flag
   174  		return
   175  	}
   176  	s.Status &= (^flag)
   177  }
   178  
   179  // GetNextPreparedStmtID generates and returns the next session scope prepared statement id.
   180  func (s *SessionVars) GetNextPreparedStmtID() uint32 {
   181  	s.preparedStmtID++
   182  	return s.preparedStmtID
   183  }
   184  
   185  // SetCurrentUser saves the current user to the session context.
   186  func (s *SessionVars) SetCurrentUser(user string) {
   187  	s.User = user
   188  }