...

Source file src/database/sql/ctxutil.go

     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	}
   149	

View as plain text