github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/src/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, execer driver.Execer, query string, nvdargs []driver.NamedValue) (driver.Result, error) {
    30  	if execerCtx, is := execer.(driver.ExecerContext); is {
    31  		return execerCtx.ExecContext(ctx, query, nvdargs)
    32  	}
    33  	dargs, err := namedValueToValue(nvdargs)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  
    38  	resi, err := execer.Exec(query, dargs)
    39  	if err == nil {
    40  		select {
    41  		default:
    42  		case <-ctx.Done():
    43  			return resi, ctx.Err()
    44  		}
    45  	}
    46  	return resi, err
    47  }
    48  
    49  func ctxDriverQuery(ctx context.Context, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) {
    50  	if queryerCtx, is := queryer.(driver.QueryerContext); is {
    51  		ret, err := queryerCtx.QueryContext(ctx, query, nvdargs)
    52  		return ret, err
    53  	}
    54  	dargs, err := namedValueToValue(nvdargs)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	rowsi, err := queryer.Query(query, dargs)
    60  	if err == nil {
    61  		select {
    62  		default:
    63  		case <-ctx.Done():
    64  			rowsi.Close()
    65  			return nil, ctx.Err()
    66  		}
    67  	}
    68  	return rowsi, err
    69  }
    70  
    71  func ctxDriverStmtExec(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Result, error) {
    72  	if siCtx, is := si.(driver.StmtExecContext); is {
    73  		return siCtx.ExecContext(ctx, nvdargs)
    74  	}
    75  	dargs, err := namedValueToValue(nvdargs)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	resi, err := si.Exec(dargs)
    81  	if err == nil {
    82  		select {
    83  		default:
    84  		case <-ctx.Done():
    85  			return resi, ctx.Err()
    86  		}
    87  	}
    88  	return resi, err
    89  }
    90  
    91  func ctxDriverStmtQuery(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Rows, error) {
    92  	if siCtx, is := si.(driver.StmtQueryContext); is {
    93  		return siCtx.QueryContext(ctx, nvdargs)
    94  	}
    95  	dargs, err := namedValueToValue(nvdargs)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  
   100  	rowsi, err := si.Query(dargs)
   101  	if err == nil {
   102  		select {
   103  		default:
   104  		case <-ctx.Done():
   105  			rowsi.Close()
   106  			return nil, ctx.Err()
   107  		}
   108  	}
   109  	return rowsi, err
   110  }
   111  
   112  var errLevelNotSupported = errors.New("sql: selected isolation level is not supported")
   113  
   114  func ctxDriverBegin(ctx context.Context, opts *TxOptions, ci driver.Conn) (driver.Tx, error) {
   115  	if ciCtx, is := ci.(driver.ConnBeginTx); is {
   116  		dopts := driver.TxOptions{}
   117  		if opts != nil {
   118  			dopts.Isolation = driver.IsolationLevel(opts.Isolation)
   119  			dopts.ReadOnly = opts.ReadOnly
   120  		}
   121  		return ciCtx.BeginTx(ctx, dopts)
   122  	}
   123  
   124  	if ctx.Done() == context.Background().Done() {
   125  		return ci.Begin()
   126  	}
   127  
   128  	if opts != nil {
   129  		// Check the transaction level. If the transaction level is non-default
   130  		// then return an error here as the BeginTx driver value is not supported.
   131  		if opts.Isolation != LevelDefault {
   132  			return nil, errors.New("sql: driver does not support non-default isolation level")
   133  		}
   134  
   135  		// If a read-only transaction is requested return an error as the
   136  		// BeginTx driver value is not supported.
   137  		if opts.ReadOnly {
   138  			return nil, errors.New("sql: driver does not support read-only transactions")
   139  		}
   140  	}
   141  
   142  	txi, err := ci.Begin()
   143  	if err == nil {
   144  		select {
   145  		default:
   146  		case <-ctx.Done():
   147  			txi.Rollback()
   148  			return nil, ctx.Err()
   149  		}
   150  	}
   151  	return txi, err
   152  }
   153  
   154  func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
   155  	dargs := make([]driver.Value, len(named))
   156  	for n, param := range named {
   157  		if len(param.Name) > 0 {
   158  			return nil, errors.New("sql: driver does not support the use of Named Parameters")
   159  		}
   160  		dargs[n] = param.Value
   161  	}
   162  	return dargs, nil
   163  }