func (s *session) processDone(t token) (err error) {
	if t == doneInProcToken && s.done.status&doneProc == 0 {
		return nil
	}
	if s.done.status&doneCount != 0 || s.done.status&doneProc != 0 {
		s.res.hasAffectedRows = true
		s.res.affectedRows = int64(s.done.count)
	}
	if s.done.status&doneError != 0 && s.res.lastError == nil {
		s.res.lastError = errors.New("unknow error reported by done token")
	}
	s.res.final = s.done.status&doneMoreResults == 0
	if s.res.final {
		if s.res.lastError != nil {
			return s.res.lastError
		}
		return io.EOF
	}
	return nil
}
process the done token's information (row count, error status, final ?)
package tds
import (
	"context"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/tls"
	"database/sql"
	"database/sql/driver"
	"encoding/asn1"
	"encoding/pem"
	"fmt"
	"io"
	"net"
	"regexp"
	"strconv"
	"time"
	"errors"
)
var validHost = regexp.MustCompile("([[:alpha:]]|[_.-])*:[0-9]+$")
var ErrUnsupportedPassWordEncrytion = errors.New("tds: login failed. Unsupported encryption")
var logoutTimeout = 5
var isError = func(s SybError) bool {
	return s.Severity > 10
}
type session struct {
	valid       bool
	charConvert bool
	res         *Result  
	b            *buf
	c            io.ReadWriteCloser  
	capabilities capabilities        
	packetSize   int
	readTimeout  int
	writeTimeout int
	loginTimeout int
	database   string
	charset    string
	language   string
	server     string
	serverType string
	envChange    envChange
	done         done
	returnStatus returnStatus
	sqlMessage   sqlMessage
	state *state
	messageMap map[token]messageReader
	IsError func(SybError) bool
}
func newLogin(prm connParams) *login {
	l := &login{library: defaultLibrary, protocolVersion: defaultProtocolVersion,
		libraryVersion: defaultLibraryVersion, charset: prm.charset,
		clientHost: prm.clientHost, user: prm.user,
		encrypted: loginSecEncrypt1 | loginSecEncrypt2 | loginSecNonce,
		app:       prm.app, packetSize: prm.packetSize, pid: prm.pid}
	if prm.encryptPassword == "no" {
		l.encrypted = 0
		l.password, l.password2 = prm.password, prm.password
	}
	return l
}
func newSession(prm connParams) (s *session, err error) {
	s = &session{envChange: envChange{msg: newMsg(envChangeToken)},
		done:         done{msg: newMsg(doneToken)},
		sqlMessage:   sqlMessage{msg: newMsg(sqlMessageToken)},
		returnStatus: returnStatus{msg: newMsg(returnStatusToken)},
		IsError:      isError, packetSize: prm.packetSize,
		readTimeout: prm.readTimeout, writeTimeout: prm.writeTimeout,
		loginTimeout: prm.loginTimeout, res: &Result{lastError: nil}}
	s.res.s = s
	s.server = prm.host
	s.messageMap = map[token]messageReader{envChangeToken: &s.envChange,
		doneProcToken: &s.done, doneInProcToken: &s.done,
		doneToken: &s.done, returnStatusToken: &s.returnStatus,
		sqlMessageToken: &s.sqlMessage}
	if s.c, err = dial(prm); err != nil {
		return s, err
	}
	s.b = newBuf(s.packetSize, s.c)
	s.b.ReadTimeout, s.b.WriteTimeout = s.readTimeout, s.writeTimeout
	s.b.defaultMessageMap = s.messageMap
	s.state = &state{handler: func(t token) error {
		var err error
		switch t {
		case sqlMessageToken:
			err = s.processsqlMessage()
		case envChangeToken:
			err = s.processEnvChange()
		case returnStatusToken:
			err = s.processReturnStatus()
		case doneProcToken, doneInProcToken, doneToken:
			err = s.processDone(token(t))
		}
		return err
	}}
	if err = s.login(prm); err != nil {
		if err == ErrUnsupportedPassWordEncrytion && prm.encryptPassword == "try" {
			s.c.Close()
			prm.encryptPassword = "no"
			return newSession(prm)
		}
		return s, err
	}
	return s, nil
}
func dial(prm connParams) (io.ReadWriteCloser, error) {
	if prm.ssl == "on" {
		return tls.DialWithDialer(&net.Dialer{Timeout: time.Duration(prm.loginTimeout) * time.Second},
			"tcp", prm.host, &tls.Config{InsecureSkipVerify: true})
	}
	return net.DialTimeout("tcp", prm.host,
		time.Duration(prm.loginTimeout)*time.Second)
}
func (s *session) login(prm connParams) (err error) {
	login := newLogin(prm)
	login.msg = msg{flags: fixedSize}
	s.capabilities = *newCapabilities()
	s.capabilities.msg = newMsg(capabilitiesToken)
	login.setCapabilities(s.capabilities)
	ctx, cancel := context.WithTimeout(context.Background(),
		time.Duration(s.loginTimeout)*time.Second)
	defer cancel()
	if err = s.b.send(ctx, loginPacket, login, &login.capabilities); err != nil {
		return fmt.Errorf("tds: login send failed: %s", err)
	}
	s.clearResult()
	loginAck := &loginAck{msg: newMsg(loginAckToken)}
	pf := &columns{msg: newMsg(paramFmtToken)}
	wpf := &columns{msg: newMsg(paramFmt2Token), flags: wide | param}
	p := &row{msg: newMsg(paramToken)}
	try := 0
loginResponse:
	for f := s.initState(ctx,
		map[token]messageReader{loginAckToken: loginAck,
			capabilitiesToken: &s.capabilities,
			paramFmtToken:     pf,
			paramFmt2Token:    wpf,
			paramToken:        p}); f != nil; f = f(s.state) {
		switch s.state.t {
		case paramFmtToken:
			p.columns = pf.fmts
		case paramFmt2Token:
			p.columns = wpf.fmts
		}
	}
	if s.state.err != nil && s.state.err != io.EOF {
		return s.state.err
	}
	if len(p.data) > 0 && try == 0 {
		if rsa, ok := p.data[0].(int64); ok {
			if rsa != 1 {
				return ErrUnsupportedPassWordEncrytion
			}
		} else {
			return ErrUnsupportedPassWordEncrytion
		}
		try = 1
		block, _ := pem.Decode(p.data[1].([]byte))
		if block == nil {
			return ErrUnsupportedPassWordEncrytion
		}
		var pk rsa.PublicKey
		_, err := asn1.Unmarshal(block.Bytes, &pk)
		if err != nil {
			return ErrUnsupportedPassWordEncrytion
		}
		var message []byte
		if len(p.data) > 2 {
			nonce := p.data[2].([]byte)
			message = append(nonce, []byte(prm.password)...)
		} else {
			return ErrUnsupportedPassWordEncrytion
		}
		ciphertext, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, &pk, message, []byte{})
		if err != nil {
			return ErrUnsupportedPassWordEncrytion
		}
		msg1 := &sybMsg{msg: newMsg(msgToken), field1: 0x01, field2: 0x0001F}
		msg2 := &sybMsg{msg: newMsg(msgToken), field1: 0x01, field2: 0x0020}
		cols1 := &columns{msg: newMsg(paramFmtToken), fmts: []colFmt{
			{colType: getType(longBinaryType, 2147483647)},
		}}
		row1 := &row{msg: newMsg(paramToken), data: []driver.Value{ciphertext},
			columns: cols1.fmts[:]}
		cols2 := &columns{msg: newMsg(paramFmtToken), fmts: []colFmt{
			{colType: getType(varcharType, 255)},
			{colType: getType(longBinaryType, 2147483647)},
		}}
		row2 := &row{msg: newMsg(paramToken), data: []driver.Value{"", ciphertext},
			columns: cols2.fmts[:]}
		if err = s.b.send(ctx, normalPacket, msg1, cols1, row1, msg2, cols2, row2); err != nil {
			return fmt.Errorf("tds: login send failed: %s", err)
		}
		goto loginResponse
	}
	if loginAck.ack != 5 {
		return errors.New("tds: login failed. Please check username/password")
	}
	s.valid = true
	s.serverType = loginAck.server
	if prm.database != "" {
		if _, err = s.simpleExec(ctx, "use "+prm.database); err != nil {
			return fmt.Errorf("tds: use database failed: %s", err)
		}
	}
	return err
}
func (s *session) checkErr(err error, msg string, ignoreEOF bool) error {
	if !s.valid {
		return driver.ErrBadConn
	}
	switch err {
	case nil:
		return nil
	case io.EOF:
		if ignoreEOF {
			return nil
		}
		return io.EOF
	case context.Canceled, context.DeadlineExceeded:
		return err
	}
	if _, ok := err.(SybError); !ok {
		s.valid = false
	}
	return fmt.Errorf("%s: %s", msg, err)
}
func (s *session) Close() error {
	if s.c == nil {
		s.valid = false
		return nil
	}
	defer s.c.Close()
	ctx, cancel := context.WithTimeout(context.Background(),
		time.Duration(logoutTimeout)*time.Second)
	defer cancel()
	if err := s.b.send(ctx, normalPacket,
		logout{msg: newMsg(logoutToken)}); err != nil {
		return fmt.Errorf("tds: close failed: %s", err)
	}
	return nil
}
func (s *session) Begin() (driver.Tx, error) {
	return s.BeginTx(nil,
		driver.TxOptions{Isolation: driver.IsolationLevel(sql.LevelDefault)})
}
var ErrInvalidIsolationLevel = errors.New("tds: invalid or unsupported isolation level")
var ErrNoReadOnly = errors.New("tds: readonly is unsupported")
var isolationLevelMap = []int{isolationReadCommited, isolationReadUncommited,
	isolationReadCommited, isolationNotImplemented,
	isolationRepeatableRead, isolationNotImplemented, isolationSerializable,
	isolationNotImplemented}
func (s *session) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
	if !s.valid {
		return s, driver.ErrBadConn
	}
	if opts.ReadOnly {
		return s, ErrNoReadOnly
	}
	if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault {
		if int(opts.Isolation) > len(isolationLevelMap) {
			return s, ErrInvalidIsolationLevel
		}
		level := isolationLevelMap[int(opts.Isolation)]
		if level == isolationNotImplemented {
			return s, ErrInvalidIsolationLevel
		}
		optCmd := optionCmd{msg: newMsg(optionCmdToken), command: optionSet,
			option: optionIsolationLevel, value: level}
		if err := s.b.send(ctx, normalPacket, &optCmd); err != nil {
			s.valid = false
			return s, s.checkErr(err, "tds: isolation level set failed", false)
		}
		for f := s.initState(ctx, map[token]messageReader{}); f != nil; f = f(s.state) {
		}
		if s.state.err = s.checkErr(s.state.err, "tds: isolation level set failed", true); s.state.err != nil {
			s.valid = false
			return s, s.state.err
		}
	}
	_, err := s.simpleExec(ctx, `begin tran
		if @@transtate != 0 raiserror 25000 'Invalid transaction state'`)
	return s, s.checkErr(err, "tds: begin failed", true)
}
func (s *session) Commit() error {
	_, err := s.simpleExec(nil, `if @@trancount > 0 commit tran
							if @@transtate != 1 raiserror 25000 'Invalid transaction state'`)
	return s.checkErr(err, "tds: commit failed", true)
}
func (s *session) Rollback() error {
	_, err := s.simpleExec(nil, `if @@trancount > 0 rollback tran
							if @@transtate != 3 raiserror 25000 'Invalid transaction state'`)
	return s.checkErr(err, "tds: rollback failed", true)
}
func (s *session) Ping(ctx context.Context) error {
	if !s.valid {
		return driver.ErrBadConn
	}
	_, err := s.SelectValue(ctx, "")
	if err != nil {
		return err
	}
	return nil
}
func (s *session) Query(query string, args []driver.Value) (driver.Rows, error) {
	if len(args) != 0 {
		return nil, driver.ErrSkip
	}
	return s.simpleQuery(nil, query)
}
func (s *session) QueryContext(ctx context.Context, query string,
	namedArgs []driver.NamedValue) (driver.Rows, error) {
	if len(namedArgs) != 0 {
		return nil, driver.ErrSkip
	}
	return s.simpleQuery(ctx, query)
}
func (s *session) simpleQuery(ctx context.Context, query string) (rows *Rows, err error) {
	if !s.valid {
		return &emptyRows, driver.ErrBadConn
	}
	if err := s.b.send(ctx, normalPacket, &language{msg: newMsg(languageToken), query: query}); err != nil {
		s.valid = false
		return &emptyRows, s.checkErr(err, "tds: query send failed", false)
	}
	s.clearResult()
	return newRow(ctx, s)
}
func (s *session) Exec(query string, args []driver.Value) (driver.Result, error) {
	if len(args) != 0 {
		return &emptyResult, driver.ErrSkip
	}
	return s.simpleExec(nil, query)
}
func (s *session) ExecContext(ctx context.Context, query string,
	namedArgs []driver.NamedValue) (driver.Result, error) {
	if len(namedArgs) != 0 {
		return &emptyResult, driver.ErrSkip
	}
	return s.simpleExec(ctx, query)
}
func (s *session) simpleExec(ctx context.Context, query string) (res *Result, err error) {
	if !s.valid {
		return &emptyResult, driver.ErrBadConn
	}
	rows, err := s.simpleQuery(ctx, query)
	if err = s.checkErr(err, "tds: exec failed", true); err != nil {
		return &emptyResult, err
	}
	rows.Close()
	return &(*s.res), nil
}
func (s *session) Prepare(query string) (driver.Stmt, error) {
	if !s.valid {
		return &emptyStmt, driver.ErrBadConn
	}
	return newStmt(nil, s, query)
}
func (s *session) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
	if !s.valid {
		return &emptyStmt, driver.ErrBadConn
	}
	return newStmt(ctx, s, query)
}
func (s *session) SelectValue(ctx context.Context, query string) (value interface{}, err error) {
	rows, err := s.simpleQuery(ctx, query)
	if err != nil {
		return nil, s.checkErr(err, "tds: select value failed", false)
	}
	defer rows.Close()
	vals := make([]driver.Value, 1)
	err = rows.Next(vals)
	if err != io.EOF && err != nil {
		return nil, err
	}
	return vals[0], nil
}
func (s *session) clearResult() {
	s.res.affectedRows, s.res.returnStatus = 0, 0
	s.res.hasError, s.res.hasAffectedRows, s.res.hasReturnStatus, s.res.final = false, false, false, false
	s.res.messages = nil
	s.res.lastError = nil
}
func newState(ctx context.Context, msg map[token]messageReader,
	handler func(token) error) *state {
	return &state{msg: msg, ctx: ctx, handler: handler}
}
func (s *session) initState(ctx context.Context,
	messages map[token]messageReader) stateFn {
	s.state.ctx, s.state.msg = ctx, messages
	s.state.err = nil
	return s.b.receive(s.state)
}
func (s *session) processsqlMessage() (err error) {
	s.res.messages = append(s.res.messages, s.sqlMessage.SybError)
	if s.IsError(s.sqlMessage.SybError) {
		s.res.lastError = s.sqlMessage.SybError
	}
	return nil
}
func (s *session) processEnvChange() (err error) {
	switch s.envChange.changeType {
	default:
		return fmt.Errorf("tds: unknow env change type: %#x",
			s.envChange.changeType)
	case dbChange:
		s.database = s.envChange.newValue
	case langChange:
		s.language = s.envChange.newValue
	case charsetChange:
		switch s.envChange.newValue {
		default:
			if err = s.b.SetCharset(s.envChange.newValue); err != nil {
				return fmt.Errorf("tds: cannot encode to '%s' charset: %s", s.envChange.newValue, err)
			}
			s.charset = s.envChange.newValue
			s.charConvert = true
		case "":
			if err = s.b.SetCharset(s.envChange.oldValue); err != nil {
				return fmt.Errorf("tds: cannot encode to '%s' charset: %s", s.envChange.oldValue, err)
			}
			s.charset = s.envChange.oldValue
			s.charConvert = true
		case "utf8":
			s.charset = s.envChange.newValue
		}
	case packetSizeChange:
		if packetSize, err := strconv.Atoi(s.envChange.newValue); err == nil {
			s.packetSize = packetSize
			s.b.PacketSize = packetSize
		}
	}
	return nil
}