dialect/sql: add HasPrefixFold and HasSuffixFold predicates (#4233)

* FieldHasPrefixFold and HasPrefixFold predicates

* FieldHasSuffixFold and HasSuffixFold predicates

* Review feedback - per dialect SQL generation.
This commit is contained in:
Mohsin Hijazee
2024-10-09 15:32:48 +02:00
committed by GitHub
parent 9627017062
commit d1dab301c6
4 changed files with 180 additions and 22 deletions

View File

@@ -1716,6 +1716,32 @@ func (p *Predicate) escapedLike(col, left, right, word string) *Predicate {
})
}
// ContainsFold is a helper predicate that applies the LIKE predicate with case-folding.
func (p *Predicate) escapedLikeFold(col, left, substr, right string) *Predicate {
return p.Append(func(b *Builder) {
w, escaped := escape(substr)
switch b.dialect {
case dialect.MySQL:
// We assume the CHARACTER SET is configured to utf8mb4,
// because this how it is defined in dialect/sql/schema.
b.Ident(col).WriteString(" COLLATE utf8mb4_general_ci LIKE ")
b.Arg(left + strings.ToLower(w) + right)
case dialect.Postgres:
b.Ident(col).WriteString(" ILIKE ")
b.Arg(left + strings.ToLower(w) + right)
default: // SQLite.
var f Func
f.SetDialect(b.dialect)
f.Lower(col)
b.WriteString(f.String()).WriteString(" LIKE ")
b.Arg(left + strings.ToLower(w) + right)
if escaped {
p.WriteString(" ESCAPE ").Arg("\\")
}
}
})
}
// HasPrefix is a helper predicate that checks prefix using the LIKE predicate.
func HasPrefix(col, prefix string) *Predicate {
return P().HasPrefix(col, prefix)
@@ -1726,6 +1752,16 @@ func (p *Predicate) HasPrefix(col, prefix string) *Predicate {
return p.escapedLike(col, "", "%", prefix)
}
// HasPrefixFold is a helper predicate that checks prefix using the ILIKE predicate.
func HasPrefixFold(col, prefix string) *Predicate {
return P().HasPrefixFold(col, prefix)
}
// HasPrefixFold is a helper predicate that checks prefix using the ILIKE predicate.
func (p *Predicate) HasPrefixFold(col, prefix string) *Predicate {
return p.escapedLikeFold(col, "", prefix, "%")
}
// ColumnsHasPrefix appends a new predicate that checks if the given column begins with the other column (prefix).
func ColumnsHasPrefix(col, prefixC string) *Predicate {
return P().ColumnsHasPrefix(col, prefixC)
@@ -1760,6 +1796,14 @@ func (p *Predicate) HasSuffix(col, suffix string) *Predicate {
return p.escapedLike(col, "%", "", suffix)
}
// HasSuffixFold is a helper predicate that checks suffix using the ILIKE predicate.
func HasSuffixFold(col, suffix string) *Predicate { return P().HasSuffixFold(col, suffix) }
// HasSuffixFold is a helper predicate that checks suffix using the ILIKE predicate.
func (p *Predicate) HasSuffixFold(col, suffix string) *Predicate {
return p.escapedLikeFold(col, "%", suffix, "")
}
// EqualFold is a helper predicate that applies the "=" predicate with case-folding.
func EqualFold(col, sub string) *Predicate { return P().EqualFold(col, sub) }
@@ -1800,28 +1844,7 @@ func ContainsFold(col, sub string) *Predicate { return P().ContainsFold(col, sub
// ContainsFold is a helper predicate that applies the LIKE predicate with case-folding.
func (p *Predicate) ContainsFold(col, substr string) *Predicate {
return p.Append(func(b *Builder) {
w, escaped := escape(substr)
switch b.dialect {
case dialect.MySQL:
// We assume the CHARACTER SET is configured to utf8mb4,
// because this how it is defined in dialect/sql/schema.
b.Ident(col).WriteString(" COLLATE utf8mb4_general_ci LIKE ")
b.Arg("%" + strings.ToLower(w) + "%")
case dialect.Postgres:
b.Ident(col).WriteString(" ILIKE ")
b.Arg("%" + strings.ToLower(w) + "%")
default: // SQLite.
var f Func
f.SetDialect(b.dialect)
f.Lower(col)
b.WriteString(f.String()).WriteString(" LIKE ")
b.Arg("%" + strings.ToLower(w) + "%")
if escaped {
p.WriteString(" ESCAPE ").Arg("\\")
}
}
})
return p.escapedLikeFold(col, "%", substr, "%")
}
// CompositeGT returns a composite ">" predicate