github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/database/sql/ctxutil.go (about)

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sql
     6  
     7  import (
     8  	"context"
     9  	"database/sql/driver"
    10  	"errors"
    11  )
    12  
    13  func ctxDriverPrepare(ctx context.Context, ci driver.Conn, query string) (driver.Stmt, error) {
    14  	if ciCtx, is := ci.(driver.ConnPrepareContext); is {
    15  		return ciCtx.PrepareContext(ctx, query)
    16  	}
    17  	si, err := ci.Prepare(query)
    18  	if err == nil {
    19  		select {
    20  		default:
    21  		case <-ctx.Done():
    22  			si.Close()
    23  			return nil, ctx.Err()
    24  		}
    25  	}
    26  	return si, err
    27  }
    28  
    29  func ctxDriverExec(ctx context.Context, execerCtx driver.ExecerContext, execer driver.Execer, query string, nvdargs []driver.NamedValue) (driver.Result, error) {
    30  	if execerCtx != nil {
    31  		return execerCtx.ExecContext(ctx, query, nvdargs)
    32  	}
    33  	dargs, err := namedValueToValue(nvdargs)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	select {
    39  	default:
    40  	case <-ctx.Done():
    41  		return nil, ctx.Err()
    42  	}
    43  	return execer.Exec(query, dargs)
    44  }
    45  
    46  func ctxDriverQuery(ctx context.Context, queryerCtx driver.QueryerContext, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) {
    47  	if queryerCtx != nil {
    48  		return queryerCtx.QueryContext(ctx, query, nvdargs)
    49  	}
    50  	dargs, err := namedValueToValue(nvdargs)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	select {
    56  	default:
    57  	case <-ctx.Done():
    58  		return nil, ctx.Err()
    59  	}
    60  	return queryer.Query(query, dargs)
    61  }
    62  
    63  func ctxDriverStmtExec(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Result, error) {
    64  	if siCtx, is := si.(driver.StmtExecContext); is {
    65  		return siCtx.ExecContext(ctx, nvdargs)
    66  	}
    67  	dargs, err := namedValueToValue(nvdargs)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	select {
    73  	default:
    74  	case <-ctx.Done():
    75  		return nil, ctx.Err()
    76  	}
    77  	return si.Exec(dargs)
    78  }
    79  
    80  func ctxDriverStmtQuery(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Rows, error) {
    81  	if siCtx, is := si.(driver.StmtQueryContext); is {
    82  		return siCtx.QueryContext(ctx, nvdargs)
    83  	}
    84  	dargs, err := namedValueToValue(nvdargs)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	select {
    90  	default:
    91  	case <-ctx.Done():
    92  		return nil, ctx.Err()
    93  	}
    94  	return si.Query(dargs)
    95  }
    96  
    97  var errLevelNotSupported = errors.New("sql: selected isolation level is not supported")
    98  
    99  func ctxDriverBegin(ctx context.Context, opts *TxOptions, ci driver.Conn) (driver.Tx, error) {
   100  	if ciCtx, is := ci.(driver.ConnBeginTx); is {
   101  		dopts := driver.TxOptions{}
   102  		if opts != nil {
   103  			dopts.Isolation = driver.IsolationLevel(opts.Isolation)
   104  			dopts.ReadOnly = opts.ReadOnly
   105  		}
   106  		return ciCtx.BeginTx(ctx, dopts)
   107  	}
   108  
   109  	if opts != nil {
   110  		// Check the transaction level. If the transaction level is non-default
   111  		// then return an error here as the BeginTx driver value is not supported.
   112  		if opts.Isolation != LevelDefault {
   113  			return nil, errors.New("sql: driver does not support non-default isolation level")
   114  		}
   115  
   116  		// If a read-only transaction is requested return an error as the
   117  		// BeginTx driver value is not supported.
   118  		if opts.ReadOnly {
   119  			return nil, errors.New("sql: driver does not support read-only transactions")
   120  		}
   121  	}
   122  
   123  	if ctx.Done() == nil {
   124  		return ci.Begin()
   125  	}
   126  
   127  	txi, err := ci.Begin()
   128  	if err == nil {
   129  		select {
   130  		default:
   131  		case <-ctx.Done():
   132  			txi.Rollback()
   133  			return nil, ctx.Err()
   134  		}
   135  	}
   136  	return txi, err
   137  }
   138  
   139  func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
   140  	dargs := make([]driver.Value, len(named))
   141  	for n, param := range named {
   142  		if len(param.Name) > 0 {
   143  			return nil, errors.New("sql: driver does not support the use of Named Parameters")
   144  		}
   145  		dargs[n] = param.Value
   146  	}
   147  	return dargs, nil
   148  }