PR c++/85515
[official-gcc.git] / libgo / go / database / sql / ctxutil.go
blobaf2afd5aa5704326d4799f53c33deb9faf003ebb
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.
5 package sql
7 import (
8 "context"
9 "database/sql/driver"
10 "errors"
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)
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()
26 return si, err
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)
33 dargs, err := namedValueToValue(nvdargs)
34 if err != nil {
35 return nil, err
38 select {
39 default:
40 case <-ctx.Done():
41 return nil, ctx.Err()
43 return execer.Exec(query, dargs)
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)
50 dargs, err := namedValueToValue(nvdargs)
51 if err != nil {
52 return nil, err
55 select {
56 default:
57 case <-ctx.Done():
58 return nil, ctx.Err()
60 return queryer.Query(query, dargs)
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)
67 dargs, err := namedValueToValue(nvdargs)
68 if err != nil {
69 return nil, err
72 select {
73 default:
74 case <-ctx.Done():
75 return nil, ctx.Err()
77 return si.Exec(dargs)
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)
84 dargs, err := namedValueToValue(nvdargs)
85 if err != nil {
86 return nil, err
89 select {
90 default:
91 case <-ctx.Done():
92 return nil, ctx.Err()
94 return si.Query(dargs)
97 var errLevelNotSupported = errors.New("sql: selected isolation level is not supported")
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
106 return ciCtx.BeginTx(ctx, dopts)
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")
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")
123 if ctx.Done() == nil {
124 return ci.Begin()
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()
136 return txi, err
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")
145 dargs[n] = param.Value
147 return dargs, nil