• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

go-sql-driver / mysql / 3601392501

pending completion
3601392501

push

github

GitHub
update changelog for Version 1.7 (#1376)

2932 of 3584 relevant lines covered (81.81%)

1490385.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.7
/statement.go
1
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
2
//
3
// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
4
//
5
// This Source Code Form is subject to the terms of the Mozilla Public
6
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
7
// You can obtain one at http://mozilla.org/MPL/2.0/.
8

9
package mysql
10

11
import (
12
        "database/sql/driver"
13
        "encoding/json"
14
        "fmt"
15
        "io"
16
        "reflect"
17
)
18

19
type mysqlStmt struct {
20
        mc         *mysqlConn
21
        id         uint32
22
        paramCount int
23
}
24

25
func (stmt *mysqlStmt) Close() error {
4,941✔
26
        if stmt.mc == nil || stmt.mc.closed.Load() {
5,103✔
27
                // driver.Stmt.Close can be called more than once, thus this function
162✔
28
                // has to be idempotent.
162✔
29
                // See also Issue #450 and golang/go#16019.
162✔
30
                //errLog.Print(ErrInvalidConn)
162✔
31
                return driver.ErrBadConn
162✔
32
        }
162✔
33

34
        err := stmt.mc.writeCommandPacketUint32(comStmtClose, stmt.id)
4,779✔
35
        stmt.mc = nil
4,779✔
36
        return err
4,779✔
37
}
38

39
func (stmt *mysqlStmt) NumInput() int {
5,724✔
40
        return stmt.paramCount
5,724✔
41
}
5,724✔
42

43
func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
×
44
        return converter{}
×
45
}
×
46

47
func (stmt *mysqlStmt) CheckNamedValue(nv *driver.NamedValue) (err error) {
10,622,016✔
48
        nv.Value, err = converter{}.ConvertValue(nv.Value)
10,622,016✔
49
        return
10,622,016✔
50
}
10,622,016✔
51

52
func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
2,376✔
53
        if stmt.mc.closed.Load() {
2,403✔
54
                errLog.Print(ErrInvalidConn)
27✔
55
                return nil, driver.ErrBadConn
27✔
56
        }
27✔
57
        // Send command
58
        err := stmt.writeExecutePacket(args)
2,349✔
59
        if err != nil {
2,349✔
60
                return nil, stmt.mc.markBadConn(err)
×
61
        }
×
62

63
        mc := stmt.mc
2,349✔
64

2,349✔
65
        mc.affectedRows = 0
2,349✔
66
        mc.insertId = 0
2,349✔
67

2,349✔
68
        // Read Result
2,349✔
69
        resLen, err := mc.readResultSetHeaderPacket()
2,349✔
70
        if err != nil {
2,430✔
71
                return nil, err
81✔
72
        }
81✔
73

74
        if resLen > 0 {
2,268✔
75
                // Columns
×
76
                if err = mc.readUntilEOF(); err != nil {
×
77
                        return nil, err
×
78
                }
×
79

80
                // Rows
81
                if err := mc.readUntilEOF(); err != nil {
×
82
                        return nil, err
×
83
                }
×
84
        }
85

86
        if err := mc.discardResults(); err != nil {
2,268✔
87
                return nil, err
×
88
        }
×
89

90
        return &mysqlResult{
2,268✔
91
                affectedRows: int64(mc.affectedRows),
2,268✔
92
                insertId:     int64(mc.insertId),
2,268✔
93
        }, nil
2,268✔
94
}
95

96
func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
×
97
        return stmt.query(args)
×
98
}
×
99

100
func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) {
3,402✔
101
        if stmt.mc.closed.Load() {
3,402✔
102
                errLog.Print(ErrInvalidConn)
×
103
                return nil, driver.ErrBadConn
×
104
        }
×
105
        // Send command
106
        err := stmt.writeExecutePacket(args)
3,402✔
107
        if err != nil {
3,402✔
108
                return nil, stmt.mc.markBadConn(err)
×
109
        }
×
110

111
        mc := stmt.mc
3,402✔
112

3,402✔
113
        // Read Result
3,402✔
114
        resLen, err := mc.readResultSetHeaderPacket()
3,402✔
115
        if err != nil {
3,483✔
116
                return nil, err
81✔
117
        }
81✔
118

119
        rows := new(binaryRows)
3,321✔
120

3,321✔
121
        if resLen > 0 {
6,642✔
122
                rows.mc = mc
3,321✔
123
                rows.rs.columns, err = mc.readColumns(resLen)
3,321✔
124
        } else {
3,321✔
125
                rows.rs.done = true
×
126

×
127
                switch err := rows.NextResultSet(); err {
×
128
                case nil, io.EOF:
×
129
                        return rows, nil
×
130
                default:
×
131
                        return nil, err
×
132
                }
133
        }
134

135
        return rows, err
3,321✔
136
}
137

138
var jsonType = reflect.TypeOf(json.RawMessage{})
139

140
type converter struct{}
141

142
// ConvertValue mirrors the reference/default converter in database/sql/driver
143
// with _one_ exception.  We support uint64 with their high bit and the default
144
// implementation does not.  This function should be kept in sync with
145
// database/sql/driver defaultConverter.ConvertValue() except for that
146
// deliberate difference.
147
func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
10,629,711✔
148
        if driver.IsValue(v) {
21,255,426✔
149
                return v, nil
10,625,715✔
150
        }
10,625,715✔
151

152
        if vr, ok := v.(driver.Valuer); ok {
4,509✔
153
                sv, err := callValuerValue(vr)
513✔
154
                if err != nil {
594✔
155
                        return nil, err
81✔
156
                }
81✔
157
                if driver.IsValue(sv) {
837✔
158
                        return sv, nil
405✔
159
                }
405✔
160
                // A value returned from the Valuer interface can be "a type handled by
161
                // a database driver's NamedValueChecker interface" so we should accept
162
                // uint64 here as well.
163
                if u, ok := sv.(uint64); ok {
54✔
164
                        return u, nil
27✔
165
                }
27✔
166
                return nil, fmt.Errorf("non-Value type %T returned from Value", sv)
×
167
        }
168
        rv := reflect.ValueOf(v)
3,483✔
169
        switch rv.Kind() {
3,483✔
170
        case reflect.Ptr:
27✔
171
                // indirect pointers
27✔
172
                if rv.IsNil() {
27✔
173
                        return nil, nil
×
174
                } else {
27✔
175
                        return c.ConvertValue(rv.Elem().Interface())
27✔
176
                }
27✔
177
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
2,187✔
178
                return rv.Int(), nil
2,187✔
179
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
513✔
180
                return rv.Uint(), nil
513✔
181
        case reflect.Float32, reflect.Float64:
270✔
182
                return rv.Float(), nil
270✔
183
        case reflect.Bool:
27✔
184
                return rv.Bool(), nil
27✔
185
        case reflect.Slice:
351✔
186
                switch t := rv.Type(); {
351✔
187
                case t == jsonType:
297✔
188
                        return v, nil
297✔
189
                case t.Elem().Kind() == reflect.Uint8:
27✔
190
                        return rv.Bytes(), nil
27✔
191
                default:
27✔
192
                        return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, t.Elem().Kind())
27✔
193
                }
194
        case reflect.String:
27✔
195
                return rv.String(), nil
27✔
196
        }
197
        return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
81✔
198
}
199

200
var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
201

202
// callValuerValue returns vr.Value(), with one exception:
203
// If vr.Value is an auto-generated method on a pointer type and the
204
// pointer is nil, it would panic at runtime in the panicwrap
205
// method. Treat it like nil instead.
206
//
207
// This is so people can implement driver.Value on value types and
208
// still use nil pointers to those types to mean nil/NULL, just like
209
// string/*string.
210
//
211
// This is an exact copy of the same-named unexported function from the
212
// database/sql package.
213
func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
513✔
214
        if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
513✔
215
                rv.IsNil() &&
513✔
216
                rv.Type().Elem().Implements(valuerReflectType) {
648✔
217
                return nil, nil
135✔
218
        }
135✔
219
        return vr.Value()
378✔
220
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc