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

huandu / go-sqlbuilder / 15616763260

12 Jun 2025 05:05PM UTC coverage: 96.527% (+0.001%) from 96.526%
15616763260

push

github

huandu
fix #200: PostgreSQL InsertIgnoreInto with subquery doesn't append ON CONFLICT DO NOTHING

1 of 1 new or added line in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

3530 of 3657 relevant lines covered (96.53%)

1.09 hits per line

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

99.07
/cond.go
1
// Copyright 2018 Huan Du. All rights reserved.
2
// Licensed under the MIT license that can be found in the LICENSE file.
3

4
package sqlbuilder
5

6
const (
7
        lparen = "("
8
        rparen = ")"
9
        opOR   = " OR "
10
        opAND  = " AND "
11
        opNOT  = "NOT "
12
)
13

14
const minIndexBase = 256
15

16
// Cond provides several helper methods to build conditions.
17
type Cond struct {
18
        Args *Args
19
}
20

21
// NewCond returns a new Cond.
22
func NewCond() *Cond {
1✔
23
        return &Cond{
1✔
24
                Args: &Args{
1✔
25
                        // Based on the discussion in #174, users may call this method to create
1✔
26
                        // `Cond` for building various conditions, which is a misuse, but we
1✔
27
                        // cannot completely prevent this error. To facilitate users in
1✔
28
                        // identifying the issue when they make mistakes and to avoid
1✔
29
                        // unexpected stackoverflows, the base index for `Args` is
1✔
30
                        // deliberately set to a larger non-zero value here. This can
1✔
31
                        // significantly reduce the likelihood of issues and allows for
1✔
32
                        // timely error notification to users.
1✔
33
                        indexBase: minIndexBase,
1✔
34
                },
1✔
35
        }
1✔
36
}
1✔
37

38
// Equal is used to construct the expression "field = value".
39
func (c *Cond) Equal(field string, value interface{}) string {
1✔
40
        if len(field) == 0 {
2✔
41
                return ""
1✔
42
        }
1✔
43

44
        return c.Var(condBuilder{
1✔
45
                Builder: func(ctx *argsCompileContext) {
2✔
46
                        ctx.WriteString(field)
1✔
47
                        ctx.WriteString(" = ")
1✔
48
                        ctx.WriteValue(value)
1✔
49
                },
1✔
50
        })
51
}
52

53
// E is an alias of Equal.
54
func (c *Cond) E(field string, value interface{}) string {
1✔
55
        return c.Equal(field, value)
1✔
56
}
1✔
57

58
// EQ is an alias of Equal.
59
func (c *Cond) EQ(field string, value interface{}) string {
1✔
60
        return c.Equal(field, value)
1✔
61
}
1✔
62

63
// NotEqual is used to construct the expression "field <> value".
64
func (c *Cond) NotEqual(field string, value interface{}) string {
1✔
65
        if len(field) == 0 {
2✔
66
                return ""
1✔
67
        }
1✔
68

69
        return c.Var(condBuilder{
1✔
70
                Builder: func(ctx *argsCompileContext) {
2✔
71
                        ctx.WriteString(field)
1✔
72
                        ctx.WriteString(" <> ")
1✔
73
                        ctx.WriteValue(value)
1✔
74
                },
1✔
75
        })
76
}
77

78
// NE is an alias of NotEqual.
79
func (c *Cond) NE(field string, value interface{}) string {
1✔
80
        return c.NotEqual(field, value)
1✔
81
}
1✔
82

83
// NEQ is an alias of NotEqual.
84
func (c *Cond) NEQ(field string, value interface{}) string {
1✔
85
        return c.NotEqual(field, value)
1✔
86
}
1✔
87

88
// GreaterThan is used to construct the expression "field > value".
89
func (c *Cond) GreaterThan(field string, value interface{}) string {
1✔
90
        if len(field) == 0 {
2✔
91
                return ""
1✔
92
        }
1✔
93

94
        return c.Var(condBuilder{
1✔
95
                Builder: func(ctx *argsCompileContext) {
2✔
96
                        ctx.WriteString(field)
1✔
97
                        ctx.WriteString(" > ")
1✔
98
                        ctx.WriteValue(value)
1✔
99
                },
1✔
100
        })
101
}
102

103
// G is an alias of GreaterThan.
104
func (c *Cond) G(field string, value interface{}) string {
1✔
105
        return c.GreaterThan(field, value)
1✔
106
}
1✔
107

108
// GT is an alias of GreaterThan.
109
func (c *Cond) GT(field string, value interface{}) string {
1✔
110
        return c.GreaterThan(field, value)
1✔
111
}
1✔
112

113
// GreaterEqualThan is used to construct the expression "field >= value".
114
func (c *Cond) GreaterEqualThan(field string, value interface{}) string {
1✔
115
        if len(field) == 0 {
2✔
116
                return ""
1✔
117
        }
1✔
118

119
        return c.Var(condBuilder{
1✔
120
                Builder: func(ctx *argsCompileContext) {
2✔
121
                        ctx.WriteString(field)
1✔
122
                        ctx.WriteString(" >= ")
1✔
123
                        ctx.WriteValue(value)
1✔
124
                },
1✔
125
        })
126
}
127

128
// GE is an alias of GreaterEqualThan.
129
func (c *Cond) GE(field string, value interface{}) string {
1✔
130
        return c.GreaterEqualThan(field, value)
1✔
131
}
1✔
132

133
// GTE is an alias of GreaterEqualThan.
134
func (c *Cond) GTE(field string, value interface{}) string {
1✔
135
        return c.GreaterEqualThan(field, value)
1✔
136
}
1✔
137

138
// LessThan is used to construct the expression "field < value".
139
func (c *Cond) LessThan(field string, value interface{}) string {
1✔
140
        if len(field) == 0 {
2✔
141
                return ""
1✔
142
        }
1✔
143

144
        return c.Var(condBuilder{
1✔
145
                Builder: func(ctx *argsCompileContext) {
2✔
146
                        ctx.WriteString(field)
1✔
147
                        ctx.WriteString(" < ")
1✔
148
                        ctx.WriteValue(value)
1✔
149
                },
1✔
150
        })
151
}
152

153
// L is an alias of LessThan.
154
func (c *Cond) L(field string, value interface{}) string {
1✔
155
        return c.LessThan(field, value)
1✔
156
}
1✔
157

158
// LT is an alias of LessThan.
159
func (c *Cond) LT(field string, value interface{}) string {
1✔
160
        return c.LessThan(field, value)
1✔
161
}
1✔
162

163
// LessEqualThan is used to construct the expression "field <= value".
164
func (c *Cond) LessEqualThan(field string, value interface{}) string {
1✔
165
        if len(field) == 0 {
2✔
166
                return ""
1✔
167
        }
1✔
168
        return c.Var(condBuilder{
1✔
169
                Builder: func(ctx *argsCompileContext) {
2✔
170
                        ctx.WriteString(field)
1✔
171
                        ctx.WriteString(" <= ")
1✔
172
                        ctx.WriteValue(value)
1✔
173
                },
1✔
174
        })
175
}
176

177
// LE is an alias of LessEqualThan.
178
func (c *Cond) LE(field string, value interface{}) string {
1✔
179
        return c.LessEqualThan(field, value)
1✔
180
}
1✔
181

182
// LTE is an alias of LessEqualThan.
183
func (c *Cond) LTE(field string, value interface{}) string {
1✔
184
        return c.LessEqualThan(field, value)
1✔
185
}
1✔
186

187
// In is used to construct the expression "field IN (value...)".
188
func (c *Cond) In(field string, values ...interface{}) string {
1✔
189
        if len(field) == 0 {
2✔
190
                return ""
1✔
191
        }
1✔
192

193
        // Empty values means "false".
194
        if len(values) == 0 {
2✔
195
                return "0 = 1"
1✔
196
        }
1✔
197

198
        return c.Var(condBuilder{
1✔
199
                Builder: func(ctx *argsCompileContext) {
2✔
200
                        ctx.WriteString(field)
1✔
201
                        ctx.WriteString(" IN (")
1✔
202
                        ctx.WriteValues(values, ", ")
1✔
203
                        ctx.WriteString(")")
1✔
204
                },
1✔
205
        })
206
}
207

208
// NotIn is used to construct the expression "field NOT IN (value...)".
209
func (c *Cond) NotIn(field string, values ...interface{}) string {
1✔
210
        if len(field) == 0 {
2✔
211
                return ""
1✔
212
        }
1✔
213

214
        // Empty values means "true".
215
        if len(values) == 0 {
2✔
216
                return "0 = 0"
1✔
217
        }
1✔
218

219
        return c.Var(condBuilder{
1✔
220
                Builder: func(ctx *argsCompileContext) {
2✔
221
                        ctx.WriteString(field)
1✔
222
                        ctx.WriteString(" NOT IN (")
1✔
223
                        ctx.WriteValues(values, ", ")
1✔
224
                        ctx.WriteString(")")
1✔
225
                },
1✔
226
        })
227
}
228

229
// Like is used to construct the expression "field LIKE value".
230
func (c *Cond) Like(field string, value interface{}) string {
1✔
231
        if len(field) == 0 {
2✔
232
                return ""
1✔
233
        }
1✔
234

235
        return c.Var(condBuilder{
1✔
236
                Builder: func(ctx *argsCompileContext) {
2✔
237
                        ctx.WriteString(field)
1✔
238
                        ctx.WriteString(" LIKE ")
1✔
239
                        ctx.WriteValue(value)
1✔
240
                },
1✔
241
        })
242
}
243

244
// ILike is used to construct the expression "field ILIKE value".
245
//
246
// When the database system does not support the ILIKE operator,
247
// the ILike method will return "LOWER(field) LIKE LOWER(value)"
248
// to simulate the behavior of the ILIKE operator.
249
func (c *Cond) ILike(field string, value interface{}) string {
1✔
250
        if len(field) == 0 {
2✔
251
                return ""
1✔
252
        }
1✔
253

254
        return c.Var(condBuilder{
1✔
255
                Builder: func(ctx *argsCompileContext) {
2✔
256
                        switch ctx.Flavor {
1✔
257
                        case PostgreSQL, SQLite:
1✔
258
                                ctx.WriteString(field)
1✔
259
                                ctx.WriteString(" ILIKE ")
1✔
260
                                ctx.WriteValue(value)
1✔
261

262
                        default:
1✔
263
                                // Use LOWER to simulate ILIKE.
1✔
264
                                ctx.WriteString("LOWER(")
1✔
265
                                ctx.WriteString(field)
1✔
266
                                ctx.WriteString(") LIKE LOWER(")
1✔
267
                                ctx.WriteValue(value)
1✔
268
                                ctx.WriteString(")")
1✔
269
                        }
270
                },
271
        })
272
}
273

274
// NotLike is used to construct the expression "field NOT LIKE value".
275
func (c *Cond) NotLike(field string, value interface{}) string {
1✔
276
        if len(field) == 0 {
2✔
277
                return ""
1✔
278
        }
1✔
279

280
        return c.Var(condBuilder{
1✔
281
                Builder: func(ctx *argsCompileContext) {
2✔
282
                        ctx.WriteString(field)
1✔
283
                        ctx.WriteString(" NOT LIKE ")
1✔
284
                        ctx.WriteValue(value)
1✔
285
                },
1✔
286
        })
287
}
288

289
// NotILike is used to construct the expression "field NOT ILIKE value".
290
//
291
// When the database system does not support the ILIKE operator,
292
// the NotILike method will return "LOWER(field) NOT LIKE LOWER(value)"
293
// to simulate the behavior of the ILIKE operator.
294
func (c *Cond) NotILike(field string, value interface{}) string {
1✔
295
        if len(field) == 0 {
2✔
296
                return ""
1✔
297
        }
1✔
298

299
        return c.Var(condBuilder{
1✔
300
                Builder: func(ctx *argsCompileContext) {
2✔
301
                        switch ctx.Flavor {
1✔
302
                        case PostgreSQL, SQLite:
1✔
303
                                ctx.WriteString(field)
1✔
304
                                ctx.WriteString(" NOT ILIKE ")
1✔
305
                                ctx.WriteValue(value)
1✔
306

307
                        default:
1✔
308
                                // Use LOWER to simulate ILIKE.
1✔
309
                                ctx.WriteString("LOWER(")
1✔
310
                                ctx.WriteString(field)
1✔
311
                                ctx.WriteString(") NOT LIKE LOWER(")
1✔
312
                                ctx.WriteValue(value)
1✔
313
                                ctx.WriteString(")")
1✔
314
                        }
315
                },
316
        })
317
}
318

319
// IsNull is used to construct the expression "field IS NULL".
320
func (c *Cond) IsNull(field string) string {
1✔
321
        if len(field) == 0 {
2✔
322
                return ""
1✔
323
        }
1✔
324

325
        return c.Var(condBuilder{
1✔
326
                Builder: func(ctx *argsCompileContext) {
2✔
327
                        ctx.WriteString(field)
1✔
328
                        ctx.WriteString(" IS NULL")
1✔
329
                },
1✔
330
        })
331
}
332

333
// IsNotNull is used to construct the expression "field IS NOT NULL".
334
func (c *Cond) IsNotNull(field string) string {
1✔
335
        if len(field) == 0 {
2✔
336
                return ""
1✔
337
        }
1✔
338
        return c.Var(condBuilder{
1✔
339
                Builder: func(ctx *argsCompileContext) {
2✔
340
                        ctx.WriteString(field)
1✔
341
                        ctx.WriteString(" IS NOT NULL")
1✔
342
                },
1✔
343
        })
344
}
345

346
// Between is used to construct the expression "field BETWEEN lower AND upper".
347
func (c *Cond) Between(field string, lower, upper interface{}) string {
1✔
348
        if len(field) == 0 {
2✔
349
                return ""
1✔
350
        }
1✔
351

352
        return c.Var(condBuilder{
1✔
353
                Builder: func(ctx *argsCompileContext) {
2✔
354
                        ctx.WriteString(field)
1✔
355
                        ctx.WriteString(" BETWEEN ")
1✔
356
                        ctx.WriteValue(lower)
1✔
357
                        ctx.WriteString(" AND ")
1✔
358
                        ctx.WriteValue(upper)
1✔
359
                },
1✔
360
        })
361
}
362

363
// NotBetween is used to construct the expression "field NOT BETWEEN lower AND upper".
364
func (c *Cond) NotBetween(field string, lower, upper interface{}) string {
1✔
365
        if len(field) == 0 {
2✔
366
                return ""
1✔
367
        }
1✔
368

369
        return c.Var(condBuilder{
1✔
370
                Builder: func(ctx *argsCompileContext) {
2✔
371
                        ctx.WriteString(field)
1✔
372
                        ctx.WriteString(" NOT BETWEEN ")
1✔
373
                        ctx.WriteValue(lower)
1✔
374
                        ctx.WriteString(" AND ")
1✔
375
                        ctx.WriteValue(upper)
1✔
376
                },
1✔
377
        })
378
}
379

380
// Or is used to construct the expression OR logic like "expr1 OR expr2 OR expr3".
381
func (c *Cond) Or(orExpr ...string) string {
1✔
382
        orExpr = filterEmptyStrings(orExpr)
1✔
383

1✔
384
        if len(orExpr) == 0 {
2✔
385
                return ""
1✔
386
        }
1✔
387

388
        exprByteLen := estimateStringsBytes(orExpr)
1✔
389
        if exprByteLen == 0 {
1✔
UNCOV
390
                return ""
×
UNCOV
391
        }
×
392

393
        buf := newStringBuilder()
1✔
394

1✔
395
        // Ensure that there is only 1 memory allocation.
1✔
396
        size := len(lparen) + len(rparen) + (len(orExpr)-1)*len(opOR) + exprByteLen
1✔
397
        buf.Grow(size)
1✔
398

1✔
399
        buf.WriteString(lparen)
1✔
400
        buf.WriteStrings(orExpr, opOR)
1✔
401
        buf.WriteString(rparen)
1✔
402
        return buf.String()
1✔
403
}
404

405
// And is used to construct the expression AND logic like "expr1 AND expr2 AND expr3".
406
func (c *Cond) And(andExpr ...string) string {
1✔
407
        andExpr = filterEmptyStrings(andExpr)
1✔
408

1✔
409
        if len(andExpr) == 0 {
2✔
410
                return ""
1✔
411
        }
1✔
412

413
        exprByteLen := estimateStringsBytes(andExpr)
1✔
414
        if exprByteLen == 0 {
1✔
UNCOV
415
                return ""
×
UNCOV
416
        }
×
417

418
        buf := newStringBuilder()
1✔
419

1✔
420
        // Ensure that there is only 1 memory allocation.
1✔
421
        size := len(lparen) + len(rparen) + (len(andExpr)-1)*len(opAND) + exprByteLen
1✔
422
        buf.Grow(size)
1✔
423

1✔
424
        buf.WriteString(lparen)
1✔
425
        buf.WriteStrings(andExpr, opAND)
1✔
426
        buf.WriteString(rparen)
1✔
427
        return buf.String()
1✔
428
}
429

430
// Not is used to construct the expression "NOT expr".
431
func (c *Cond) Not(notExpr string) string {
1✔
432
        if len(notExpr) == 0 {
2✔
433
                return ""
1✔
434
        }
1✔
435

436
        buf := newStringBuilder()
1✔
437

1✔
438
        // Ensure that there is only 1 memory allocation.
1✔
439
        size := len(opNOT) + len(notExpr)
1✔
440
        buf.Grow(size)
1✔
441

1✔
442
        buf.WriteString(opNOT)
1✔
443
        buf.WriteString(notExpr)
1✔
444
        return buf.String()
1✔
445
}
446

447
// Exists is used to construct the expression "EXISTS (subquery)".
448
func (c *Cond) Exists(subquery interface{}) string {
1✔
449
        return c.Var(condBuilder{
1✔
450
                Builder: func(ctx *argsCompileContext) {
2✔
451
                        ctx.WriteString("EXISTS (")
1✔
452
                        ctx.WriteValue(subquery)
1✔
453
                        ctx.WriteString(")")
1✔
454
                },
1✔
455
        })
456
}
457

458
// NotExists is used to construct the expression "NOT EXISTS (subquery)".
459
func (c *Cond) NotExists(subquery interface{}) string {
1✔
460
        return c.Var(condBuilder{
1✔
461
                Builder: func(ctx *argsCompileContext) {
2✔
462
                        ctx.WriteString("NOT EXISTS (")
1✔
463
                        ctx.WriteValue(subquery)
1✔
464
                        ctx.WriteString(")")
1✔
465
                },
1✔
466
        })
467
}
468

469
// Any is used to construct the expression "field op ANY (value...)".
470
func (c *Cond) Any(field, op string, values ...interface{}) string {
1✔
471
        if len(field) == 0 || len(op) == 0 {
2✔
472
                return ""
1✔
473
        }
1✔
474

475
        // Empty values means "false".
476
        if len(values) == 0 {
2✔
477
                return "0 = 1"
1✔
478
        }
1✔
479

480
        return c.Var(condBuilder{
1✔
481
                Builder: func(ctx *argsCompileContext) {
2✔
482
                        ctx.WriteString(field)
1✔
483
                        ctx.WriteString(" ")
1✔
484
                        ctx.WriteString(op)
1✔
485
                        ctx.WriteString(" ANY (")
1✔
486
                        ctx.WriteValues(values, ", ")
1✔
487
                        ctx.WriteString(")")
1✔
488
                },
1✔
489
        })
490
}
491

492
// All is used to construct the expression "field op ALL (value...)".
493
func (c *Cond) All(field, op string, values ...interface{}) string {
1✔
494
        if len(field) == 0 || len(op) == 0 {
2✔
495
                return ""
1✔
496
        }
1✔
497

498
        // Empty values means "false".
499
        if len(values) == 0 {
2✔
500
                return "0 = 1"
1✔
501
        }
1✔
502

503
        return c.Var(condBuilder{
1✔
504
                Builder: func(ctx *argsCompileContext) {
2✔
505
                        ctx.WriteString(field)
1✔
506
                        ctx.WriteString(" ")
1✔
507
                        ctx.WriteString(op)
1✔
508
                        ctx.WriteString(" ALL (")
1✔
509
                        ctx.WriteValues(values, ", ")
1✔
510
                        ctx.WriteString(")")
1✔
511
                },
1✔
512
        })
513
}
514

515
// Some is used to construct the expression "field op SOME (value...)".
516
func (c *Cond) Some(field, op string, values ...interface{}) string {
1✔
517
        if len(field) == 0 || len(op) == 0 {
2✔
518
                return ""
1✔
519
        }
1✔
520

521
        // Empty values means "false".
522
        if len(values) == 0 {
2✔
523
                return "0 = 1"
1✔
524
        }
1✔
525

526
        return c.Var(condBuilder{
1✔
527
                Builder: func(ctx *argsCompileContext) {
2✔
528
                        ctx.WriteString(field)
1✔
529
                        ctx.WriteString(" ")
1✔
530
                        ctx.WriteString(op)
1✔
531
                        ctx.WriteString(" SOME (")
1✔
532
                        ctx.WriteValues(values, ", ")
1✔
533
                        ctx.WriteString(")")
1✔
534
                },
1✔
535
        })
536
}
537

538
// IsDistinctFrom is used to construct the expression "field IS DISTINCT FROM value".
539
//
540
// When the database system does not support the IS DISTINCT FROM operator,
541
// the NotILike method will return "NOT field <=> value" for MySQL or a
542
// "CASE ... WHEN ... ELSE ... END" expression to simulate the behavior of
543
// the IS DISTINCT FROM operator.
544
func (c *Cond) IsDistinctFrom(field string, value interface{}) string {
1✔
545
        if len(field) == 0 {
2✔
546
                return ""
1✔
547
        }
1✔
548

549
        return c.Var(condBuilder{
1✔
550
                Builder: func(ctx *argsCompileContext) {
2✔
551
                        switch ctx.Flavor {
1✔
552
                        case PostgreSQL, SQLite, SQLServer:
1✔
553
                                ctx.WriteString(field)
1✔
554
                                ctx.WriteString(" IS DISTINCT FROM ")
1✔
555
                                ctx.WriteValue(value)
1✔
556

557
                        case MySQL:
1✔
558
                                ctx.WriteString("NOT ")
1✔
559
                                ctx.WriteString(field)
1✔
560
                                ctx.WriteString(" <=> ")
1✔
561
                                ctx.WriteValue(value)
1✔
562

563
                        default:
1✔
564
                                // CASE
1✔
565
                                //     WHEN field IS NULL AND value IS NULL THEN 0
1✔
566
                                //     WHEN field IS NOT NULL AND value IS NOT NULL AND field = value THEN 0
1✔
567
                                //     ELSE 1
1✔
568
                                // END = 1
1✔
569
                                ctx.WriteString("CASE WHEN ")
1✔
570
                                ctx.WriteString(field)
1✔
571
                                ctx.WriteString(" IS NULL AND ")
1✔
572
                                ctx.WriteValue(value)
1✔
573
                                ctx.WriteString(" IS NULL THEN 0 WHEN ")
1✔
574
                                ctx.WriteString(field)
1✔
575
                                ctx.WriteString(" IS NOT NULL AND ")
1✔
576
                                ctx.WriteValue(value)
1✔
577
                                ctx.WriteString(" IS NOT NULL AND ")
1✔
578
                                ctx.WriteString(field)
1✔
579
                                ctx.WriteString(" = ")
1✔
580
                                ctx.WriteValue(value)
1✔
581
                                ctx.WriteString(" THEN 0 ELSE 1 END = 1")
1✔
582
                        }
583
                },
584
        })
585
}
586

587
// IsNotDistinctFrom is used to construct the expression "field IS NOT DISTINCT FROM value".
588
//
589
// When the database system does not support the IS NOT DISTINCT FROM operator,
590
// the NotILike method will return "field <=> value" for MySQL or a
591
// "CASE ... WHEN ... ELSE ... END" expression to simulate the behavior of
592
// the IS NOT DISTINCT FROM operator.
593
func (c *Cond) IsNotDistinctFrom(field string, value interface{}) string {
1✔
594
        if len(field) == 0 {
2✔
595
                return ""
1✔
596
        }
1✔
597

598
        return c.Var(condBuilder{
1✔
599
                Builder: func(ctx *argsCompileContext) {
2✔
600
                        switch ctx.Flavor {
1✔
601
                        case PostgreSQL, SQLite, SQLServer:
1✔
602
                                ctx.WriteString(field)
1✔
603
                                ctx.WriteString(" IS NOT DISTINCT FROM ")
1✔
604
                                ctx.WriteValue(value)
1✔
605

606
                        case MySQL:
1✔
607
                                ctx.WriteString(field)
1✔
608
                                ctx.WriteString(" <=> ")
1✔
609
                                ctx.WriteValue(value)
1✔
610

611
                        default:
1✔
612
                                // CASE
1✔
613
                                //     WHEN field IS NULL AND value IS NULL THEN 1
1✔
614
                                //     WHEN field IS NOT NULL AND value IS NOT NULL AND field = value THEN 1
1✔
615
                                //     ELSE 0
1✔
616
                                // END = 1
1✔
617
                                ctx.WriteString("CASE WHEN ")
1✔
618
                                ctx.WriteString(field)
1✔
619
                                ctx.WriteString(" IS NULL AND ")
1✔
620
                                ctx.WriteValue(value)
1✔
621
                                ctx.WriteString(" IS NULL THEN 1 WHEN ")
1✔
622
                                ctx.WriteString(field)
1✔
623
                                ctx.WriteString(" IS NOT NULL AND ")
1✔
624
                                ctx.WriteValue(value)
1✔
625
                                ctx.WriteString(" IS NOT NULL AND ")
1✔
626
                                ctx.WriteString(field)
1✔
627
                                ctx.WriteString(" = ")
1✔
628
                                ctx.WriteValue(value)
1✔
629
                                ctx.WriteString(" THEN 1 ELSE 0 END = 1")
1✔
630
                        }
631
                },
632
        })
633
}
634

635
// Var returns a placeholder for value.
636
func (c *Cond) Var(value interface{}) string {
1✔
637
        return c.Args.Add(value)
1✔
638
}
1✔
639

640
type condBuilder struct {
641
        Builder func(ctx *argsCompileContext)
642
}
643

644
func estimateStringsBytes(strs []string) (n int) {
1✔
645
        for _, s := range strs {
2✔
646
                n += len(s)
1✔
647
        }
1✔
648

649
        return
1✔
650
}
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