Skip to content

Commit

Permalink
Merge pull request #175 from rodionovv/string-validation
Browse files Browse the repository at this point in the history
Ignore empty content to prevent the output of incorrect SQL
  • Loading branch information
huandu authored Oct 28, 2024
2 parents c329655 + 961c268 commit be6fb8b
Show file tree
Hide file tree
Showing 9 changed files with 312 additions and 47 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ _testmain.go
# VS Code
debug
debug_test
.vscode/

# Mac
.DS_Store
Expand Down
99 changes: 97 additions & 2 deletions cond.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func NewCond() *Cond {

// Equal is used to construct the expression "field = value".
func (c *Cond) Equal(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -46,6 +50,10 @@ func (c *Cond) EQ(field string, value interface{}) string {

// NotEqual is used to construct the expression "field <> value".
func (c *Cond) NotEqual(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -67,6 +75,10 @@ func (c *Cond) NEQ(field string, value interface{}) string {

// GreaterThan is used to construct the expression "field > value".
func (c *Cond) GreaterThan(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -88,6 +100,10 @@ func (c *Cond) GT(field string, value interface{}) string {

// GreaterEqualThan is used to construct the expression "field >= value".
func (c *Cond) GreaterEqualThan(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -109,6 +125,10 @@ func (c *Cond) GTE(field string, value interface{}) string {

// LessThan is used to construct the expression "field < value".
func (c *Cond) LessThan(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -130,6 +150,9 @@ func (c *Cond) LT(field string, value interface{}) string {

// LessEqualThan is used to construct the expression "field <= value".
func (c *Cond) LessEqualThan(field string, value interface{}) string {
if len(field) == 0 {
return ""
}
return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -151,6 +174,10 @@ func (c *Cond) LTE(field string, value interface{}) string {

// In is used to construct the expression "field IN (value...)".
func (c *Cond) In(field string, values ...interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -163,6 +190,10 @@ func (c *Cond) In(field string, values ...interface{}) string {

// NotIn is used to construct the expression "field NOT IN (value...)".
func (c *Cond) NotIn(field string, values ...interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -175,6 +206,10 @@ func (c *Cond) NotIn(field string, values ...interface{}) string {

// Like is used to construct the expression "field LIKE value".
func (c *Cond) Like(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -190,6 +225,10 @@ func (c *Cond) Like(field string, value interface{}) string {
// the ILike method will return "LOWER(field) LIKE LOWER(value)"
// to simulate the behavior of the ILIKE operator.
func (c *Cond) ILike(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
switch ctx.Flavor {
Expand All @@ -212,6 +251,10 @@ func (c *Cond) ILike(field string, value interface{}) string {

// NotLike is used to construct the expression "field NOT LIKE value".
func (c *Cond) NotLike(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -227,6 +270,10 @@ func (c *Cond) NotLike(field string, value interface{}) string {
// the NotILike method will return "LOWER(field) NOT LIKE LOWER(value)"
// to simulate the behavior of the ILIKE operator.
func (c *Cond) NotILike(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
switch ctx.Flavor {
Expand All @@ -249,6 +296,10 @@ func (c *Cond) NotILike(field string, value interface{}) string {

// IsNull is used to construct the expression "field IS NULL".
func (c *Cond) IsNull(field string) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -259,6 +310,9 @@ func (c *Cond) IsNull(field string) string {

// IsNotNull is used to construct the expression "field IS NOT NULL".
func (c *Cond) IsNotNull(field string) string {
if len(field) == 0 {
return ""
}
return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -269,6 +323,10 @@ func (c *Cond) IsNotNull(field string) string {

// Between is used to construct the expression "field BETWEEN lower AND upper".
func (c *Cond) Between(field string, lower, upper interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -282,6 +340,10 @@ func (c *Cond) Between(field string, lower, upper interface{}) string {

// NotBetween is used to construct the expression "field NOT BETWEEN lower AND upper".
func (c *Cond) NotBetween(field string, lower, upper interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -299,10 +361,15 @@ func (c *Cond) Or(orExpr ...string) string {
return ""
}

exprByteLen := estimateStringsBytes(orExpr)
if exprByteLen == 0 {
return ""
}

buf := newStringBuilder()

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

buf.WriteString(lparen)
Expand All @@ -317,10 +384,15 @@ func (c *Cond) And(andExpr ...string) string {
return ""
}

exprByteLen := estimateStringsBytes(andExpr)
if exprByteLen == 0 {
return ""
}

buf := newStringBuilder()

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

buf.WriteString(lparen)
Expand All @@ -331,6 +403,9 @@ func (c *Cond) And(andExpr ...string) string {

// Not is used to construct the expression "NOT expr".
func (c *Cond) Not(notExpr string) string {
if len(notExpr) == 0 {
return ""
}
buf := newStringBuilder()

// Ensure that there is only 1 memory allocation.
Expand Down Expand Up @@ -366,6 +441,10 @@ func (c *Cond) NotExists(subquery interface{}) string {

// Any is used to construct the expression "field op ANY (value...)".
func (c *Cond) Any(field, op string, values ...interface{}) string {
if len(field) == 0 || len(op) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -380,6 +459,10 @@ func (c *Cond) Any(field, op string, values ...interface{}) string {

// All is used to construct the expression "field op ALL (value...)".
func (c *Cond) All(field, op string, values ...interface{}) string {
if len(field) == 0 || len(op) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -394,6 +477,10 @@ func (c *Cond) All(field, op string, values ...interface{}) string {

// Some is used to construct the expression "field op SOME (value...)".
func (c *Cond) Some(field, op string, values ...interface{}) string {
if len(field) == 0 || len(op) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
ctx.WriteString(field)
Expand All @@ -413,6 +500,10 @@ func (c *Cond) Some(field, op string, values ...interface{}) string {
// "CASE ... WHEN ... ELSE ... END" expression to simulate the behavior of
// the IS DISTINCT FROM operator.
func (c *Cond) IsDistinctFrom(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
switch ctx.Flavor {
Expand Down Expand Up @@ -458,6 +549,10 @@ func (c *Cond) IsDistinctFrom(field string, value interface{}) string {
// "CASE ... WHEN ... ELSE ... END" expression to simulate the behavior of
// the IS NOT DISTINCT FROM operator.
func (c *Cond) IsNotDistinctFrom(field string, value interface{}) string {
if len(field) == 0 {
return ""
}

return c.Var(condBuilder{
Builder: func(ctx *argsCompileContext) {
switch ctx.Flavor {
Expand Down
Loading

0 comments on commit be6fb8b

Please sign in to comment.