github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 func ctxDriverBegin(ctx context.Context, opts *TxOptions, ci driver.Conn) (driver.Tx, error) { 98 if ciCtx, is := ci.(driver.ConnBeginTx); is { 99 dopts := driver.TxOptions{} 100 if opts != nil { 101 dopts.Isolation = driver.IsolationLevel(opts.Isolation) 102 dopts.ReadOnly = opts.ReadOnly 103 } 104 return ciCtx.BeginTx(ctx, dopts) 105 } 106 107 if opts != nil { 108 // Check the transaction level. If the transaction level is non-default 109 // then return an error here as the BeginTx driver value is not supported. 110 if opts.Isolation != LevelDefault { 111 return nil, errors.New("sql: driver does not support non-default isolation level") 112 } 113 114 // If a read-only transaction is requested return an error as the 115 // BeginTx driver value is not supported. 116 if opts.ReadOnly { 117 return nil, errors.New("sql: driver does not support read-only transactions") 118 } 119 } 120 121 if ctx.Done() == nil { 122 return ci.Begin() 123 } 124 125 txi, err := ci.Begin() 126 if err == nil { 127 select { 128 default: 129 case <-ctx.Done(): 130 txi.Rollback() 131 return nil, ctx.Err() 132 } 133 } 134 return txi, err 135 } 136 137 func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) { 138 dargs := make([]driver.Value, len(named)) 139 for n, param := range named { 140 if len(param.Name) > 0 { 141 return nil, errors.New("sql: driver does not support the use of Named Parameters") 142 } 143 dargs[n] = param.Value 144 } 145 return dargs, nil 146 }