1
2
3 package sqlmock
4
5 import (
6 "database/sql/driver"
7 "fmt"
8 "log"
9 "time"
10 )
11
12
13 type Sqlmock interface {
14
15 SqlmockCommon
16 }
17
18 type namedValue struct {
19 Name string
20 Ordinal int
21 Value driver.Value
22 }
23
24 func (c *sqlmock) ExpectPing() *ExpectedPing {
25 log.Println("ExpectPing has no effect on Go 1.7 or below")
26 return &ExpectedPing{}
27 }
28
29
30 func (c *sqlmock) Query(query string, args []driver.Value) (driver.Rows, error) {
31 namedArgs := make([]namedValue, len(args))
32 for i, v := range args {
33 namedArgs[i] = namedValue{
34 Ordinal: i + 1,
35 Value: v,
36 }
37 }
38
39 ex, err := c.query(query, namedArgs)
40 if ex != nil {
41 time.Sleep(ex.delay)
42 }
43 if err != nil {
44 return nil, err
45 }
46
47 return ex.rows, nil
48 }
49
50 func (c *sqlmock) query(query string, args []namedValue) (*ExpectedQuery, error) {
51 var expected *ExpectedQuery
52 var fulfilled int
53 var ok bool
54 for _, next := range c.expected {
55 next.Lock()
56 if next.fulfilled() {
57 next.Unlock()
58 fulfilled++
59 continue
60 }
61
62 if c.ordered {
63 if expected, ok = next.(*ExpectedQuery); ok {
64 break
65 }
66 next.Unlock()
67 return nil, fmt.Errorf("call to Query '%s' with args %+v, was not expected, next expectation is: %s", query, args, next)
68 }
69 if qr, ok := next.(*ExpectedQuery); ok {
70 if err := c.queryMatcher.Match(qr.expectSQL, query); err != nil {
71 next.Unlock()
72 continue
73 }
74 if err := qr.attemptArgMatch(args); err == nil {
75 expected = qr
76 break
77 }
78 }
79 next.Unlock()
80 }
81
82 if expected == nil {
83 msg := "call to Query '%s' with args %+v was not expected"
84 if fulfilled == len(c.expected) {
85 msg = "all expectations were already fulfilled, " + msg
86 }
87 return nil, fmt.Errorf(msg, query, args)
88 }
89
90 defer expected.Unlock()
91
92 if err := c.queryMatcher.Match(expected.expectSQL, query); err != nil {
93 return nil, fmt.Errorf("Query: %v", err)
94 }
95
96 if err := expected.argsMatches(args); err != nil {
97 return nil, fmt.Errorf("Query '%s', arguments do not match: %s", query, err)
98 }
99
100 expected.triggered = true
101 if expected.err != nil {
102 return expected, expected.err
103 }
104
105 if expected.rows == nil {
106 return nil, fmt.Errorf("Query '%s' with args %+v, must return a database/sql/driver.Rows, but it was not set for expectation %T as %+v", query, args, expected, expected)
107 }
108 return expected, nil
109 }
110
111
112 func (c *sqlmock) Exec(query string, args []driver.Value) (driver.Result, error) {
113 namedArgs := make([]namedValue, len(args))
114 for i, v := range args {
115 namedArgs[i] = namedValue{
116 Ordinal: i + 1,
117 Value: v,
118 }
119 }
120
121 ex, err := c.exec(query, namedArgs)
122 if ex != nil {
123 time.Sleep(ex.delay)
124 }
125 if err != nil {
126 return nil, err
127 }
128
129 return ex.result, nil
130 }
131
132 func (c *sqlmock) exec(query string, args []namedValue) (*ExpectedExec, error) {
133 var expected *ExpectedExec
134 var fulfilled int
135 var ok bool
136 for _, next := range c.expected {
137 next.Lock()
138 if next.fulfilled() {
139 next.Unlock()
140 fulfilled++
141 continue
142 }
143
144 if c.ordered {
145 if expected, ok = next.(*ExpectedExec); ok {
146 break
147 }
148 next.Unlock()
149 return nil, fmt.Errorf("call to ExecQuery '%s' with args %+v, was not expected, next expectation is: %s", query, args, next)
150 }
151 if exec, ok := next.(*ExpectedExec); ok {
152 if err := c.queryMatcher.Match(exec.expectSQL, query); err != nil {
153 next.Unlock()
154 continue
155 }
156
157 if err := exec.attemptArgMatch(args); err == nil {
158 expected = exec
159 break
160 }
161 }
162 next.Unlock()
163 }
164 if expected == nil {
165 msg := "call to ExecQuery '%s' with args %+v was not expected"
166 if fulfilled == len(c.expected) {
167 msg = "all expectations were already fulfilled, " + msg
168 }
169 return nil, fmt.Errorf(msg, query, args)
170 }
171 defer expected.Unlock()
172
173 if err := c.queryMatcher.Match(expected.expectSQL, query); err != nil {
174 return nil, fmt.Errorf("ExecQuery: %v", err)
175 }
176
177 if err := expected.argsMatches(args); err != nil {
178 return nil, fmt.Errorf("ExecQuery '%s', arguments do not match: %s", query, err)
179 }
180
181 expected.triggered = true
182 if expected.err != nil {
183 return expected, expected.err
184 }
185
186 if expected.result == nil {
187 return nil, fmt.Errorf("ExecQuery '%s' with args %+v, must return a database/sql/driver.Result, but it was not set for expectation %T as %+v", query, args, expected, expected)
188 }
189
190 return expected, nil
191 }
192
View as plain text