Skip to content

Commit aa60862

Browse files
authored
feature: add Mysql&Postgres Json Like (#225)
1 parent 84327a5 commit aa60862

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

json.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ type JSONQueryExpression struct {
110110
keys []string
111111
hasKeys bool
112112
equals bool
113+
likes bool
113114
equalsValue interface{}
114115
extract bool
115116
path string
@@ -142,6 +143,14 @@ func (jsonQuery *JSONQueryExpression) Equals(value interface{}, keys ...string)
142143
return jsonQuery
143144
}
144145

146+
// Likes return clause.Expression
147+
func (jsonQuery *JSONQueryExpression) Likes(value interface{}, keys ...string) *JSONQueryExpression {
148+
jsonQuery.keys = keys
149+
jsonQuery.likes = true
150+
jsonQuery.equalsValue = value
151+
return jsonQuery
152+
}
153+
145154
// Build implements clause.Expression
146155
func (jsonQuery *JSONQueryExpression) Build(builder clause.Builder) {
147156
if stmt, ok := builder.(*gorm.Statement); ok {
@@ -175,6 +184,19 @@ func (jsonQuery *JSONQueryExpression) Build(builder clause.Builder) {
175184
stmt.AddVar(builder, jsonQuery.equalsValue)
176185
}
177186
}
187+
case jsonQuery.likes:
188+
if len(jsonQuery.keys) > 0 {
189+
builder.WriteString("JSON_EXTRACT(")
190+
builder.WriteQuoted(jsonQuery.column)
191+
builder.WriteByte(',')
192+
builder.AddVar(stmt, jsonQueryJoin(jsonQuery.keys))
193+
builder.WriteString(") LIKE ")
194+
if value, ok := jsonQuery.equalsValue.(bool); ok {
195+
builder.WriteString(strconv.FormatBool(value))
196+
} else {
197+
stmt.AddVar(builder, jsonQuery.equalsValue)
198+
}
199+
}
178200
}
179201
case "postgres":
180202
switch {
@@ -206,6 +228,24 @@ func (jsonQuery *JSONQueryExpression) Build(builder clause.Builder) {
206228
}
207229
builder.WriteString(") = ")
208230

231+
if _, ok := jsonQuery.equalsValue.(string); ok {
232+
stmt.AddVar(builder, jsonQuery.equalsValue)
233+
} else {
234+
stmt.AddVar(builder, fmt.Sprint(jsonQuery.equalsValue))
235+
}
236+
}
237+
case jsonQuery.likes:
238+
if len(jsonQuery.keys) > 0 {
239+
builder.WriteString(fmt.Sprintf("json_extract_path_text(%v::json,", stmt.Quote(jsonQuery.column)))
240+
241+
for idx, key := range jsonQuery.keys {
242+
if idx > 0 {
243+
builder.WriteByte(',')
244+
}
245+
stmt.AddVar(builder, key)
246+
}
247+
builder.WriteString(") LIKE ")
248+
209249
if _, ok := jsonQuery.equalsValue.(string); ok {
210250
stmt.AddVar(builder, jsonQuery.equalsValue)
211251
} else {

json_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ func TestJSON(t *testing.T) {
124124
}
125125
AssertEqual(t, results9[0].Name, users[1].Name)
126126

127+
var result10 UserWithJSON
128+
if err := DB.First(&result10, datatypes.JSONQuery("attributes").Likes("%dmi%", "role")).Error; err != nil {
129+
t.Fatalf("failed to find user with json value, got error %v", err)
130+
}
131+
AssertEqual(t, result10.Name, users[1].Name)
132+
127133
// not support for sqlite
128134
// JSONOverlaps
129135
//var result9 UserWithJSON

0 commit comments

Comments
 (0)