github.com/RevenueMonster/sqlike@v1.0.6/examples/json.go (about) 1 package examples 2 3 import ( 4 "context" 5 "database/sql" 6 "encoding/json" 7 "sort" 8 "testing" 9 10 "github.com/RevenueMonster/sqlike/sql/expr" 11 "github.com/RevenueMonster/sqlike/sqlike" 12 "github.com/RevenueMonster/sqlike/sqlike/actions" 13 "github.com/RevenueMonster/sqlike/sqlike/indexes" 14 "github.com/RevenueMonster/sqlike/sqlike/options" 15 "github.com/stretchr/testify/require" 16 ) 17 18 // JSONExamples : 19 func JSONExamples(ctx context.Context, t *testing.T, db *sqlike.Database) { 20 var ( 21 err error 22 result *sqlike.Result 23 ) 24 25 table := db.Table("JSON") 26 err = table.DropIfExists(ctx) 27 require.NoError(t, err) 28 29 // migrate 30 { 31 table.MustMigrate(ctx, jsonStruct{}) 32 } 33 34 // create index 35 { 36 err = table.Indexes().CreateOne(ctx, indexes.Index{ 37 Name: "words", 38 Type: indexes.MultiValued, 39 Cast: "StrArr", 40 As: "CHAR(50) ARRAY", 41 Comment: "wording index", 42 }) 43 require.NoError(t, err) 44 } 45 46 jss := [...]jsonStruct{ 47 newJSONStruct(), 48 newJSONStruct(), 49 { 50 Text: "Hello America 🎉 !!!", 51 StrArr: []string{"Hello", "America", "🎉"}, 52 IntArr: []int{6743, 88}, 53 }, 54 } 55 56 { 57 _, err = table.Insert( 58 ctx, 59 &jss, 60 options.Insert(). 61 SetDebug(true)) 62 require.NoError(t, err) 63 } 64 65 // JSON_EXTRACT, JSON_QUOTE, JSON_UNQUOTE and JSON_KEYS 66 { 67 var ( 68 id int64 = 1 69 o struct { 70 Text string 71 Message string 72 QuoteMessage string 73 ObjKeys []string 74 } 75 ) 76 77 extr := expr.JSON_EXTRACT(expr.Column("Raw"), "$.message") 78 err = table.FindOne( 79 ctx, 80 actions.FindOne(). 81 Select( 82 expr.As(expr.JSON_QUOTE(expr.Column("Text")), "Text"), 83 expr.JSON_UNQUOTE(extr), 84 extr, 85 expr.JSON_KEYS(expr.Column("Raw")), 86 ). 87 Where( 88 expr.Equal("$Key", id), 89 ), 90 options.FindOne().SetDebug(true), 91 ).Scan(&o.Text, &o.Message, &o.QuoteMessage, &o.ObjKeys) 92 require.NoError(t, err) 93 require.Equal(t, `"TEXT"`, o.Text) 94 require.Equal(t, `ok`, o.Message) 95 require.Equal(t, `"ok"`, o.QuoteMessage) 96 97 sort.Strings(o.ObjKeys) 98 require.ElementsMatch(t, []string{ 99 "amountInCents", "category", "message", "status", "type", 100 }, o.ObjKeys) 101 102 // col = JSON_SET(col, '$.counter', JSON_EXTRACT(col, '$.counter') + 1) 103 if affected, err := table.UpdateOne( 104 ctx, 105 actions.UpdateOne(). 106 Where( 107 expr.Equal("$Key", id), 108 ). 109 Set( 110 expr.ColumnValue("Raw", 111 expr.JSON_SET( 112 expr.Column("Raw"), 113 "$.amountInCents", 114 expr.Raw("JSON_EXTRACT(`Raw`, '$.amountInCents') + 7689"), 115 ), 116 ), 117 ), 118 options.UpdateOne().SetDebug(true), 119 ); err != nil { 120 require.NoError(t, err) 121 } else if affected < 1 { 122 require.Greater(t, int64(0), affected) 123 } 124 125 var raw json.RawMessage 126 if err := table.FindOne( 127 ctx, 128 actions.FindOne(). 129 Select("Raw"). 130 Where( 131 expr.Equal("$Key", id), 132 ), 133 ).Scan(&raw); err != nil { 134 require.NoError(t, err) 135 } 136 137 var output struct { 138 Amount float64 `json:"amountInCents"` 139 } 140 141 if err := json.Unmarshal(raw, &output); err != nil { 142 require.NoError(t, err) 143 } 144 145 require.Equal(t, float64(8689), output.Amount) 146 } 147 148 // 149 { 150 type rawData struct { 151 ID int64 `json:"id"` 152 UnderscoreID int64 `json:"_id"` 153 Text string `json:"text"` 154 Emoji string `json:"emoji"` 155 Flag bool `json:"flag"` 156 } 157 158 var ( 159 id int64 160 output jsonStruct 161 js = newJSONStruct() 162 res sql.Result 163 ) 164 165 js.Raw = json.RawMessage(`{ 166 "_id": 100, 167 "text": "Hello world", 168 "emoji" : "💩💩💩" 169 }`) 170 res, err = table.InsertOne(ctx, &js) 171 require.NoError(t, err) 172 id, err = res.LastInsertId() 173 require.NoError(t, err) 174 175 if err := table.FindOne( 176 ctx, 177 actions.FindOne(). 178 Where( 179 expr.Equal("$Key", id), 180 ), 181 ).Decode(&output); err != nil { 182 require.NoError(t, err) 183 } 184 185 var raw rawData 186 err = json.Unmarshal(output.Raw, &raw) 187 require.NoError(t, err) 188 require.Equal(t, int64(0), raw.ID) 189 require.Equal(t, int64(100), raw.UnderscoreID) 190 require.Equal(t, "💩💩💩", raw.Emoji) 191 192 // rename key `_id` to `id` of json object 193 if affected, err := table.UpdateOne( 194 ctx, 195 actions.UpdateOne(). 196 Where( 197 expr.Equal("$Key", id), 198 ). 199 Set( 200 expr.ColumnValue("Raw", 201 expr.JSON_INSERT( 202 expr.JSON_REMOVE(expr.Column("Raw"), "$._id"), 203 "$.id", 204 expr.JSON_EXTRACT(expr.Column("Raw"), "$._id"), 205 ), 206 ), 207 ), 208 options.UpdateOne().SetDebug(true), 209 ); err != nil { 210 require.NoError(t, err) 211 } else if affected > 0 { 212 require.Greater(t, affected, int64(0)) 213 } 214 215 // reset the data 216 output = jsonStruct{} 217 raw = rawData{} 218 219 if err := table.FindOne( 220 ctx, 221 actions.FindOne(). 222 Where( 223 expr.Equal("$Key", id), 224 ), 225 ).Decode(&output); err != nil { 226 require.NoError(t, err) 227 } 228 229 err = json.Unmarshal(output.Raw, &raw) 230 require.NoError(t, err) 231 require.Equal(t, int64(100), raw.ID) 232 require.Equal(t, int64(0), raw.UnderscoreID) 233 require.Equal(t, "💩💩💩", raw.Emoji) 234 } 235 236 // advance query 237 { 238 type output struct { 239 Raw string 240 Message string 241 } 242 243 result, err = table.Find( 244 ctx, 245 actions.Find(). 246 Select( 247 expr.As( 248 expr.Func("REPLACE", expr.Column("Raw"), "message", "msg"), 249 "Raw", 250 ), 251 expr.As( 252 expr.JSON_UNQUOTE(expr.JSONColumn("Raw", "message")), 253 "Message", 254 ), 255 ). 256 Where( 257 expr.JSON_CONTAINS( 258 expr.Column("StrArr"), 259 expr.JSON_QUOTE("a"), 260 ), 261 expr.Equal( 262 expr.JSONColumn("Raw", "message"), 263 "ok", 264 ), 265 ). 266 OrderBy( 267 expr.Desc("$Key"), 268 ), 269 options.Find(). 270 SetDebug(true). 271 SetNoLimit(true), 272 ) 273 require.NoError(t, err) 274 275 arr := []output{} 276 err = result.All(&arr) 277 require.NoError(t, err) 278 require.True(t, len(arr) > 0) 279 require.True(t, len(arr[0].Raw) > 3) 280 require.Equal(t, "ok", arr[0].Message) 281 282 var out []jsonStruct 283 284 result, err = table.Find( 285 ctx, 286 actions.Find(). 287 Where( 288 expr.MemberOf("🎉", "StrArr"), 289 ), 290 options.Find(). 291 SetDebug(true). 292 SetNoLimit(true), 293 ) 294 require.NoError(t, err) 295 296 err = result.All(&out) 297 require.NoError(t, err) 298 299 require.Equal(t, jsonStruct{ 300 ID: 3, 301 Text: "Hello America 🎉 !!!", 302 StrArr: []string{"Hello", "America", "🎉"}, 303 IntArr: []int{6743, 88}, 304 Raw: json.RawMessage(`null`), 305 }, out[0]) 306 } 307 } 308 309 func newJSONStruct() (js jsonStruct) { 310 js.Text = "TEXT" 311 js.Raw = []byte(`{"message":"ok","type":"TNG","category":"EWALLET","status":"SUCCESS","amountInCents":1000}`) 312 js.StrArr = []string{"a", "b", "c", "d", "e", "f"} 313 js.IntArr = []int{100, 16, -2, 88, 32, -47, 25} 314 js.Struct.StringSlice = sort.StringSlice{"a", "b", "c"} 315 js.Struct.IntSlice = sort.IntSlice{0, 1, 224, 999} 316 return 317 }