1 package goqu_test
2
3 import (
4 "testing"
5
6 "github.com/DATA-DOG/go-sqlmock"
7 "github.com/doug-martin/goqu/v9"
8 "github.com/doug-martin/goqu/v9/exp"
9 "github.com/doug-martin/goqu/v9/internal/errors"
10 "github.com/doug-martin/goqu/v9/internal/sb"
11 "github.com/doug-martin/goqu/v9/mocks"
12 "github.com/stretchr/testify/mock"
13 "github.com/stretchr/testify/suite"
14 )
15
16 type (
17 deleteTestCase struct {
18 ds *goqu.DeleteDataset
19 clauses exp.DeleteClauses
20 }
21 deleteDatasetSuite struct {
22 suite.Suite
23 }
24 )
25
26 func (dds *deleteDatasetSuite) assertCases(cases ...deleteTestCase) {
27 for _, s := range cases {
28 dds.Equal(s.clauses, s.ds.GetClauses())
29 }
30 }
31
32 func (dds *deleteDatasetSuite) SetupSuite() {
33 noReturn := goqu.DefaultDialectOptions()
34 noReturn.SupportsReturn = false
35 goqu.RegisterDialect("no-return", noReturn)
36
37 limitOnDelete := goqu.DefaultDialectOptions()
38 limitOnDelete.SupportsLimitOnDelete = true
39 goqu.RegisterDialect("limit-on-delete", limitOnDelete)
40
41 orderOnDelete := goqu.DefaultDialectOptions()
42 orderOnDelete.SupportsOrderByOnDelete = true
43 goqu.RegisterDialect("order-on-delete", orderOnDelete)
44 }
45
46 func (dds *deleteDatasetSuite) TearDownSuite() {
47 goqu.DeregisterDialect("no-return")
48 goqu.DeregisterDialect("limit-on-delete")
49 goqu.DeregisterDialect("order-on-delete")
50 }
51
52 func (dds *deleteDatasetSuite) TestDelete() {
53 ds := goqu.Delete("test")
54 dds.IsType(&goqu.DeleteDataset{}, ds)
55 dds.Implements((*exp.Expression)(nil), ds)
56 dds.Implements((*exp.AppendableExpression)(nil), ds)
57 }
58
59 func (dds *deleteDatasetSuite) TestClone() {
60 ds := goqu.Delete("test")
61 dds.Equal(ds.Clone(), ds)
62 }
63
64 func (dds *deleteDatasetSuite) TestExpression() {
65 ds := goqu.Delete("test")
66 dds.Equal(ds.Expression(), ds)
67 }
68
69 func (dds *deleteDatasetSuite) TestDialect() {
70 ds := goqu.Delete("test")
71 dds.NotNil(ds.Dialect())
72 }
73
74 func (dds *deleteDatasetSuite) TestWithDialect() {
75 ds := goqu.Delete("test")
76 md := new(mocks.SQLDialect)
77 ds = ds.SetDialect(md)
78
79 dialect := goqu.GetDialect("default")
80 dialectDs := ds.WithDialect("default")
81 dds.Equal(md, ds.Dialect())
82 dds.Equal(dialect, dialectDs.Dialect())
83 }
84
85 func (dds *deleteDatasetSuite) TestPrepared() {
86 ds := goqu.Delete("test")
87 preparedDs := ds.Prepared(true)
88 dds.True(preparedDs.IsPrepared())
89 dds.False(ds.IsPrepared())
90
91 dds.True(preparedDs.Where(goqu.Ex{"a": 1}).IsPrepared())
92
93 defer goqu.SetDefaultPrepared(false)
94 goqu.SetDefaultPrepared(true)
95
96
97 ds = goqu.Delete("test")
98 dds.True(ds.IsPrepared())
99 }
100
101 func (dds *deleteDatasetSuite) TestGetClauses() {
102 ds := goqu.Delete("test")
103 ce := exp.NewDeleteClauses().SetFrom(goqu.I("test"))
104 dds.Equal(ce, ds.GetClauses())
105 }
106
107 func (dds *deleteDatasetSuite) TestWith() {
108 from := goqu.From("cte")
109 bd := goqu.Delete("items")
110 dds.assertCases(
111 deleteTestCase{
112 ds: bd.With("test-cte", from),
113 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")).
114 CommonTablesAppend(exp.NewCommonTableExpression(false, "test-cte", from)),
115 },
116 deleteTestCase{
117 ds: bd,
118 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
119 },
120 )
121 }
122
123 func (dds *deleteDatasetSuite) TestWithRecursive() {
124 from := goqu.From("cte")
125 bd := goqu.Delete("items")
126 dds.assertCases(
127 deleteTestCase{
128 ds: bd.WithRecursive("test-cte", from),
129 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")).
130 CommonTablesAppend(exp.NewCommonTableExpression(true, "test-cte", from)),
131 },
132 deleteTestCase{
133 ds: bd,
134 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
135 },
136 )
137 }
138
139 func (dds *deleteDatasetSuite) TestFrom_withIdentifier() {
140 bd := goqu.Delete("items")
141 dds.assertCases(
142 deleteTestCase{
143 ds: bd.From("items2"),
144 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items2")),
145 },
146 deleteTestCase{
147 ds: bd.From(goqu.C("items2")),
148 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items2")),
149 },
150 deleteTestCase{
151 ds: bd.From(goqu.T("items2")),
152 clauses: exp.NewDeleteClauses().SetFrom(goqu.T("items2")),
153 },
154 deleteTestCase{
155 ds: bd.From("schema.table"),
156 clauses: exp.NewDeleteClauses().SetFrom(goqu.I("schema.table")),
157 },
158 deleteTestCase{
159 ds: bd,
160 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
161 },
162 )
163
164 dds.PanicsWithValue(goqu.ErrBadFromArgument, func() {
165 goqu.Delete("test").From(true)
166 })
167 }
168
169 func (dds *deleteDatasetSuite) TestWhere() {
170 bd := goqu.Delete("items")
171 dds.assertCases(
172 deleteTestCase{
173 ds: bd.Where(goqu.Ex{"a": 1}),
174 clauses: exp.NewDeleteClauses().
175 SetFrom(goqu.C("items")).
176 WhereAppend(goqu.Ex{"a": 1}),
177 },
178 deleteTestCase{
179 ds: bd.Where(goqu.Ex{"a": 1}).Where(goqu.C("b").Eq("c")),
180 clauses: exp.NewDeleteClauses().
181 SetFrom(goqu.C("items")).
182 WhereAppend(goqu.Ex{"a": 1}).
183 WhereAppend(goqu.C("b").Eq("c")),
184 },
185 deleteTestCase{
186 ds: bd,
187 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
188 },
189 )
190 }
191
192 func (dds *deleteDatasetSuite) TestClearWhere() {
193 bd := goqu.Delete("items").Where(goqu.Ex{"a": 1})
194 dds.assertCases(
195 deleteTestCase{
196 ds: bd.ClearWhere(),
197 clauses: exp.NewDeleteClauses().
198 SetFrom(goqu.C("items")),
199 },
200 deleteTestCase{
201 ds: bd,
202 clauses: exp.NewDeleteClauses().
203 SetFrom(goqu.C("items")).
204 WhereAppend(goqu.Ex{"a": 1}),
205 },
206 )
207 }
208
209 func (dds *deleteDatasetSuite) TestOrder() {
210 bd := goqu.Delete("items")
211 dds.assertCases(
212 deleteTestCase{
213 ds: bd.Order(goqu.C("a").Asc()),
214 clauses: exp.NewDeleteClauses().
215 SetFrom(goqu.C("items")).
216 SetOrder(goqu.C("a").Asc()),
217 },
218 deleteTestCase{
219 ds: bd.Order(goqu.C("a").Asc()).Order(goqu.C("b").Desc()),
220 clauses: exp.NewDeleteClauses().
221 SetFrom(goqu.C("items")).
222 SetOrder(goqu.C("b").Desc()),
223 },
224 deleteTestCase{
225 ds: bd.Order(goqu.C("a").Asc(), goqu.C("b").Desc()),
226 clauses: exp.NewDeleteClauses().
227 SetFrom(goqu.C("items")).
228 SetOrder(goqu.C("a").Asc(), goqu.C("b").Desc()),
229 },
230 deleteTestCase{
231 ds: bd,
232 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
233 },
234 )
235 }
236
237 func (dds *deleteDatasetSuite) TestOrderAppend() {
238 bd := goqu.Delete("items").Order(goqu.C("a").Asc())
239 dds.assertCases(
240 deleteTestCase{
241 ds: bd.OrderAppend(goqu.C("b").Desc()),
242 clauses: exp.NewDeleteClauses().
243 SetFrom(goqu.C("items")).
244 SetOrder(goqu.C("a").Asc(), goqu.C("b").Desc()),
245 },
246 deleteTestCase{
247 ds: bd,
248 clauses: exp.NewDeleteClauses().
249 SetFrom(goqu.C("items")).
250 SetOrder(goqu.C("a").Asc()),
251 },
252 )
253 }
254
255 func (dds *deleteDatasetSuite) TestOrderPrepend() {
256 bd := goqu.Delete("items").Order(goqu.C("a").Asc())
257 dds.assertCases(
258 deleteTestCase{
259 ds: bd.OrderPrepend(goqu.C("b").Desc()),
260 clauses: exp.NewDeleteClauses().
261 SetFrom(goqu.C("items")).
262 SetOrder(goqu.C("b").Desc(), goqu.C("a").Asc()),
263 },
264 deleteTestCase{
265 ds: bd,
266 clauses: exp.NewDeleteClauses().
267 SetFrom(goqu.C("items")).
268 SetOrder(goqu.C("a").Asc()),
269 },
270 )
271 }
272
273 func (dds *deleteDatasetSuite) TestClearOrder() {
274 bd := goqu.Delete("items").Order(goqu.C("a").Asc())
275 dds.assertCases(
276 deleteTestCase{
277 ds: bd.ClearOrder(),
278 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
279 },
280 deleteTestCase{
281 ds: bd,
282 clauses: exp.NewDeleteClauses().
283 SetFrom(goqu.C("items")).
284 SetOrder(goqu.C("a").Asc()),
285 },
286 )
287 }
288
289 func (dds *deleteDatasetSuite) TestLimit() {
290 bd := goqu.Delete("test")
291 dds.assertCases(
292 deleteTestCase{
293 ds: bd.Limit(10),
294 clauses: exp.NewDeleteClauses().
295 SetFrom(goqu.C("test")).
296 SetLimit(uint(10)),
297 },
298 deleteTestCase{
299 ds: bd.Limit(0),
300 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
301 },
302 deleteTestCase{
303 ds: bd.Limit(10).Limit(2),
304 clauses: exp.NewDeleteClauses().
305 SetFrom(goqu.C("test")).
306 SetLimit(uint(2)),
307 },
308 deleteTestCase{
309 ds: bd.Limit(10).Limit(0),
310 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
311 },
312 deleteTestCase{
313 ds: bd,
314 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
315 },
316 )
317 }
318
319 func (dds *deleteDatasetSuite) TestLimitAll() {
320 bd := goqu.Delete("test")
321 dds.assertCases(
322 deleteTestCase{
323 ds: bd.LimitAll(),
324 clauses: exp.NewDeleteClauses().
325 SetFrom(goqu.C("test")).
326 SetLimit(goqu.L("ALL")),
327 },
328 deleteTestCase{
329 ds: bd.Limit(10).LimitAll(),
330 clauses: exp.NewDeleteClauses().
331 SetFrom(goqu.C("test")).
332 SetLimit(goqu.L("ALL")),
333 },
334 deleteTestCase{
335 ds: bd,
336 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
337 },
338 )
339 }
340
341 func (dds *deleteDatasetSuite) TestClearLimit() {
342 bd := goqu.Delete("test").Limit(10)
343 dds.assertCases(
344 deleteTestCase{
345 ds: bd.ClearLimit(),
346 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")),
347 },
348 deleteTestCase{
349 ds: bd,
350 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("test")).SetLimit(uint(10)),
351 },
352 )
353 }
354
355 func (dds *deleteDatasetSuite) TestReturning() {
356 bd := goqu.Delete("items")
357 dds.assertCases(
358 deleteTestCase{
359 ds: bd.Returning("a"),
360 clauses: exp.NewDeleteClauses().
361 SetFrom(goqu.C("items")).
362 SetReturning(exp.NewColumnListExpression("a")),
363 },
364 deleteTestCase{
365 ds: bd.Returning(),
366 clauses: exp.NewDeleteClauses().
367 SetFrom(goqu.C("items")).
368 SetReturning(exp.NewColumnListExpression()),
369 },
370 deleteTestCase{
371 ds: bd.Returning(nil),
372 clauses: exp.NewDeleteClauses().
373 SetFrom(goqu.C("items")).
374 SetReturning(exp.NewColumnListExpression()),
375 },
376 deleteTestCase{
377 ds: bd.Returning("a").Returning("b"),
378 clauses: exp.NewDeleteClauses().
379 SetFrom(goqu.C("items")).
380 SetReturning(exp.NewColumnListExpression("b")),
381 },
382 deleteTestCase{
383 ds: bd,
384 clauses: exp.NewDeleteClauses().SetFrom(goqu.C("items")),
385 },
386 )
387 }
388
389 func (dds *deleteDatasetSuite) TestReturnsColumns() {
390 ds := goqu.Delete("test")
391 dds.False(ds.ReturnsColumns())
392 dds.True(ds.Returning("foo", "bar").ReturnsColumns())
393 }
394
395 func (dds *deleteDatasetSuite) TestToSQL() {
396 md := new(mocks.SQLDialect)
397 ds := goqu.Delete("test").SetDialect(md)
398 c := ds.GetClauses()
399 sqlB := sb.NewSQLBuilder(false)
400 md.On("ToDeleteSQL", sqlB, c).Return(nil).Once()
401
402 sql, args, err := ds.ToSQL()
403 dds.Empty(sql)
404 dds.Empty(args)
405 dds.Nil(err)
406 md.AssertExpectations(dds.T())
407 }
408
409 func (dds *deleteDatasetSuite) TestToSQL_Prepared() {
410 md := new(mocks.SQLDialect)
411 ds := goqu.Delete("test").Prepared(true).SetDialect(md)
412 c := ds.GetClauses()
413 sqlB := sb.NewSQLBuilder(true)
414 md.On("ToDeleteSQL", sqlB, c).Return(nil).Once()
415
416 sql, args, err := ds.ToSQL()
417 dds.Empty(sql)
418 dds.Empty(args)
419 dds.Nil(err)
420 md.AssertExpectations(dds.T())
421 }
422
423 func (dds *deleteDatasetSuite) TestToSQL_WithError() {
424 md := new(mocks.SQLDialect)
425 ds := goqu.Delete("test").SetDialect(md)
426 c := ds.GetClauses()
427 ee := errors.New("expected error")
428 sqlB := sb.NewSQLBuilder(false)
429 md.On("ToDeleteSQL", sqlB, c).Run(func(args mock.Arguments) {
430 args.Get(0).(sb.SQLBuilder).SetError(ee)
431 }).Once()
432
433 sql, args, err := ds.ToSQL()
434 dds.Empty(sql)
435 dds.Empty(args)
436 dds.Equal(ee, err)
437 md.AssertExpectations(dds.T())
438 }
439
440 func (dds *deleteDatasetSuite) TestExecutor() {
441 mDB, _, err := sqlmock.New()
442 dds.NoError(err)
443
444 ds := goqu.New("mock", mDB).Delete("items").Where(goqu.Ex{"id": goqu.Op{"gt": 10}})
445
446 dsql, args, err := ds.Executor().ToSQL()
447 dds.NoError(err)
448 dds.Empty(args)
449 dds.Equal(`DELETE FROM "items" WHERE ("id" > 10)`, dsql)
450
451 dsql, args, err = ds.Prepared(true).Executor().ToSQL()
452 dds.NoError(err)
453 dds.Equal([]interface{}{int64(10)}, args)
454 dds.Equal(`DELETE FROM "items" WHERE ("id" > ?)`, dsql)
455
456 defer goqu.SetDefaultPrepared(false)
457 goqu.SetDefaultPrepared(true)
458
459 dsql, args, err = ds.Executor().ToSQL()
460 dds.NoError(err)
461 dds.Equal([]interface{}{int64(10)}, args)
462 dds.Equal(`DELETE FROM "items" WHERE ("id" > ?)`, dsql)
463 }
464
465 func (dds *deleteDatasetSuite) TestSetError() {
466 err1 := errors.New("error #1")
467 err2 := errors.New("error #2")
468 err3 := errors.New("error #3")
469
470
471 md := new(mocks.SQLDialect)
472 ds := goqu.Delete("test").SetDialect(md)
473 ds = ds.SetError(err1)
474 dds.Equal(err1, ds.Error())
475 sql, args, err := ds.ToSQL()
476 dds.Empty(sql)
477 dds.Empty(args)
478 dds.Equal(err1, err)
479
480
481 ds = ds.SetError(err2)
482 dds.Equal(err1, ds.Error())
483 sql, args, err = ds.ToSQL()
484 dds.Empty(sql)
485 dds.Empty(args)
486 dds.Equal(err1, err)
487
488
489 ds = ds.ClearLimit()
490 dds.Equal(err1, ds.Error())
491 sql, args, err = ds.ToSQL()
492 dds.Empty(sql)
493 dds.Empty(args)
494 dds.Equal(err1, err)
495
496
497 c := ds.GetClauses()
498 sqlB := sb.NewSQLBuilder(false)
499 md.On("ToDeleteSQL", sqlB, c).Run(func(args mock.Arguments) {
500 args.Get(0).(sb.SQLBuilder).SetError(err3)
501 }).Once()
502
503 sql, args, err = ds.ToSQL()
504 dds.Empty(sql)
505 dds.Empty(args)
506 dds.Equal(err1, err)
507 }
508
509 func TestDeleteDataset(t *testing.T) {
510 suite.Run(t, new(deleteDatasetSuite))
511 }
512
View as plain text