|
3 | 3 |
|
4 | 4 | package sqlbuilder
|
5 | 5 |
|
| 6 | +const ( |
| 7 | + lparen = "(" |
| 8 | + rparen = ")" |
| 9 | + opOR = " OR " |
| 10 | + opAND = " AND " |
| 11 | + opNOT = "NOT " |
| 12 | +) |
| 13 | + |
6 | 14 | // Cond provides several helper methods to build conditions.
|
7 | 15 | type Cond struct {
|
8 | 16 | Args *Args
|
@@ -319,26 +327,49 @@ func (c *Cond) NotBetween(field string, lower, upper interface{}) string {
|
319 | 327 |
|
320 | 328 | // Or is used to construct the expression OR logic like "expr1 OR expr2 OR expr3".
|
321 | 329 | func (c *Cond) Or(orExpr ...string) string {
|
| 330 | + if len(orExpr) == 0 { |
| 331 | + return "" |
| 332 | + } |
| 333 | + |
322 | 334 | buf := newStringBuilder()
|
323 |
| - buf.WriteString("(") |
324 |
| - buf.WriteStrings(orExpr, " OR ") |
325 |
| - buf.WriteString(")") |
| 335 | + |
| 336 | + // Ensure that there is only 1 memory allocation. |
| 337 | + size := len(lparen) + len(rparen) + (len(orExpr)-1)*len(opOR) + estimateStringsBytes(orExpr) |
| 338 | + buf.Grow(size) |
| 339 | + |
| 340 | + buf.WriteString(lparen) |
| 341 | + buf.WriteStrings(orExpr, opOR) |
| 342 | + buf.WriteString(rparen) |
326 | 343 | return buf.String()
|
327 | 344 | }
|
328 | 345 |
|
329 | 346 | // And is used to construct the expression AND logic like "expr1 AND expr2 AND expr3".
|
330 | 347 | func (c *Cond) And(andExpr ...string) string {
|
| 348 | + if len(andExpr) == 0 { |
| 349 | + return "" |
| 350 | + } |
| 351 | + |
331 | 352 | buf := newStringBuilder()
|
332 |
| - buf.WriteString("(") |
333 |
| - buf.WriteStrings(andExpr, " AND ") |
334 |
| - buf.WriteString(")") |
| 353 | + |
| 354 | + // Ensure that there is only 1 memory allocation. |
| 355 | + size := len(lparen) + len(rparen) + (len(andExpr)-1)*len(opAND) + estimateStringsBytes(andExpr) |
| 356 | + buf.Grow(size) |
| 357 | + |
| 358 | + buf.WriteString(lparen) |
| 359 | + buf.WriteStrings(andExpr, opAND) |
| 360 | + buf.WriteString(rparen) |
335 | 361 | return buf.String()
|
336 | 362 | }
|
337 | 363 |
|
338 | 364 | // Not is used to construct the expression "NOT expr".
|
339 | 365 | func (c *Cond) Not(notExpr string) string {
|
340 | 366 | buf := newStringBuilder()
|
341 |
| - buf.WriteString("NOT ") |
| 367 | + |
| 368 | + // Ensure that there is only 1 memory allocation. |
| 369 | + size := len(opNOT) + len(notExpr) |
| 370 | + buf.Grow(size) |
| 371 | + |
| 372 | + buf.WriteString(opNOT) |
342 | 373 | buf.WriteString(notExpr)
|
343 | 374 | return buf.String()
|
344 | 375 | }
|
@@ -514,3 +545,11 @@ func (c *Cond) Var(value interface{}) string {
|
514 | 545 | type condBuilder struct {
|
515 | 546 | Builder func(ctx *argsCompileContext)
|
516 | 547 | }
|
| 548 | + |
| 549 | +func estimateStringsBytes(strs []string) (n int) { |
| 550 | + for _, s := range strs { |
| 551 | + n += len(s) |
| 552 | + } |
| 553 | + |
| 554 | + return |
| 555 | +} |
0 commit comments