|
7 | 7 | using System.Threading.Tasks;
|
8 | 8 | using Redis.OM.Contracts;
|
9 | 9 | using Redis.OM.Modeling;
|
10 |
| -using StackExchange.Redis; |
11 | 10 |
|
12 | 11 | namespace Redis.OM
|
13 | 12 | {
|
@@ -187,6 +186,48 @@ public static async Task<bool> JsonSetAsync(this IRedisConnection connection, st
|
187 | 186 | return result;
|
188 | 187 | }
|
189 | 188 |
|
| 189 | + /// <summary> |
| 190 | + /// Sets a value as JSON in redis. |
| 191 | + /// </summary> |
| 192 | + /// <param name="connection">the connection.</param> |
| 193 | + /// <param name="key">the key for the object.</param> |
| 194 | + /// <param name="path">the path within the json to set.</param> |
| 195 | + /// <param name="json">the json.</param> |
| 196 | + /// <param name="when">XX - set if exist, NX - set if not exist.</param> |
| 197 | + /// <param name="timeSpan">the the timespan to set for your (TTL).</param> |
| 198 | + /// <returns>whether the operation succeeded.</returns> |
| 199 | + public static async Task<bool> JsonSetAsync(this IRedisConnection connection, string key, string path, string json, WhenKey when, TimeSpan? timeSpan = null) |
| 200 | + { |
| 201 | + var argList = new List<string> { timeSpan != null ? ((long)timeSpan.Value.TotalMilliseconds).ToString() : "-1", path, json }; |
| 202 | + switch (when) |
| 203 | + { |
| 204 | + case WhenKey.Exists: |
| 205 | + argList.Add("XX"); |
| 206 | + break; |
| 207 | + case WhenKey.NotExists: |
| 208 | + argList.Add("NX"); |
| 209 | + break; |
| 210 | + } |
| 211 | + |
| 212 | + return await connection.CreateAndEvalAsync(nameof(Scripts.JsonSetWithExpire), new[] { key }, argList.ToArray()) == 1; |
| 213 | + } |
| 214 | + |
| 215 | + /// <summary> |
| 216 | + /// Sets a value as JSON in redis. |
| 217 | + /// </summary> |
| 218 | + /// <param name="connection">the connection.</param> |
| 219 | + /// <param name="key">the key for the object.</param> |
| 220 | + /// <param name="path">the path within the json to set.</param> |
| 221 | + /// <param name="obj">the object to serialize to json.</param> |
| 222 | + /// <param name="when">XX - set if exist, NX - set if not exist.</param> |
| 223 | + /// <param name="timeSpan">the the timespan to set for your (TTL).</param> |
| 224 | + /// <returns>whether the operation succeeded.</returns> |
| 225 | + public static async Task<bool> JsonSetAsync(this IRedisConnection connection, string key, string path, object obj, WhenKey when, TimeSpan? timeSpan = null) |
| 226 | + { |
| 227 | + var json = JsonSerializer.Serialize(obj, Options); |
| 228 | + return await connection.JsonSetAsync(key, path, json, when, timeSpan); |
| 229 | + } |
| 230 | + |
190 | 231 | /// <summary>
|
191 | 232 | /// Set's values in a hash.
|
192 | 233 | /// </summary>
|
@@ -286,6 +327,48 @@ public static bool JsonSet(this IRedisConnection connection, string key, string
|
286 | 327 | return connection.JsonSet(key, path, json, timeSpan);
|
287 | 328 | }
|
288 | 329 |
|
| 330 | + /// <summary> |
| 331 | + /// Sets a value as JSON in redis. |
| 332 | + /// </summary> |
| 333 | + /// <param name="connection">the connection.</param> |
| 334 | + /// <param name="key">the key for the object.</param> |
| 335 | + /// <param name="path">the path within the json to set.</param> |
| 336 | + /// <param name="json">the json.</param> |
| 337 | + /// <param name="when">XX - set if exist, NX - set if not exist.</param> |
| 338 | + /// <param name="timeSpan">the the timespan to set for your (TTL).</param> |
| 339 | + /// <returns>whether the operation succeeded.</returns> |
| 340 | + public static bool JsonSet(this IRedisConnection connection, string key, string path, string json, WhenKey when, TimeSpan? timeSpan = null) |
| 341 | + { |
| 342 | + var argList = new List<string> { timeSpan != null ? ((long)timeSpan.Value.TotalMilliseconds).ToString() : "-1", path, json }; |
| 343 | + switch (when) |
| 344 | + { |
| 345 | + case WhenKey.Exists: |
| 346 | + argList.Add("XX"); |
| 347 | + break; |
| 348 | + case WhenKey.NotExists: |
| 349 | + argList.Add("NX"); |
| 350 | + break; |
| 351 | + } |
| 352 | + |
| 353 | + return connection.CreateAndEval(nameof(Scripts.JsonSetWithExpire), new[] { key }, argList.ToArray()) == 1; |
| 354 | + } |
| 355 | + |
| 356 | + /// <summary> |
| 357 | + /// Sets a value as JSON in redis. |
| 358 | + /// </summary> |
| 359 | + /// <param name="connection">the connection.</param> |
| 360 | + /// <param name="key">the key for the object.</param> |
| 361 | + /// <param name="path">the path within the json to set.</param> |
| 362 | + /// <param name="obj">the object to serialize to json.</param> |
| 363 | + /// <param name="when">XX - set if exist, NX - set if not exist.</param> |
| 364 | + /// <param name="timeSpan">the the timespan to set for your (TTL).</param> |
| 365 | + /// <returns>whether the operation succeeded.</returns> |
| 366 | + public static bool JsonSet(this IRedisConnection connection, string key, string path, object obj, WhenKey when, TimeSpan? timeSpan = null) |
| 367 | + { |
| 368 | + var json = JsonSerializer.Serialize(obj, Options); |
| 369 | + return connection.JsonSet(key, path, json, when, timeSpan); |
| 370 | + } |
| 371 | + |
289 | 372 | /// <summary>
|
290 | 373 | /// Serializes an object to either hash or json (depending on how it's decorated), and saves it in redis.
|
291 | 374 | /// </summary>
|
@@ -315,6 +398,108 @@ public static string Set(this IRedisConnection connection, object obj)
|
315 | 398 | return id;
|
316 | 399 | }
|
317 | 400 |
|
| 401 | + /// <summary> |
| 402 | + /// Serializes an object to either hash or json (depending on how it's decorated, and saves it to redis conditionally based on the WhenKey, |
| 403 | + /// NOTE: <see cref="WhenKey.Exists"/> will replace the object in redis if it exists. |
| 404 | + /// </summary> |
| 405 | + /// <param name="connection">The connection to redis.</param> |
| 406 | + /// <param name="obj">The object to save.</param> |
| 407 | + /// <param name="when">The condition for when to set the object.</param> |
| 408 | + /// <param name="timespan">The length of time before the key expires.</param> |
| 409 | + /// <returns>the key for the object, null if nothing was set.</returns> |
| 410 | + public static string? Set(this IRedisConnection connection, object obj, WhenKey when, TimeSpan? timespan = null) |
| 411 | + { |
| 412 | + var id = obj.SetId(); |
| 413 | + var type = obj.GetType(); |
| 414 | + |
| 415 | + if (Attribute.GetCustomAttribute(type, typeof(DocumentAttribute)) is not DocumentAttribute attr || attr.StorageType == StorageType.Hash) |
| 416 | + { |
| 417 | + if (when == WhenKey.Always) |
| 418 | + { |
| 419 | + if (timespan.HasValue) |
| 420 | + { |
| 421 | + return connection.Set(obj, timespan.Value); |
| 422 | + } |
| 423 | + |
| 424 | + return connection.Set(obj); |
| 425 | + } |
| 426 | + |
| 427 | + var kvps = obj.BuildHashSet(); |
| 428 | + var argsList = new List<string>(); |
| 429 | + int? res = null; |
| 430 | + argsList.Add(timespan != null ? ((long)timespan.Value.TotalMilliseconds).ToString() : "-1"); |
| 431 | + foreach (var kvp in kvps) |
| 432 | + { |
| 433 | + argsList.Add(kvp.Key); |
| 434 | + argsList.Add(kvp.Value); |
| 435 | + } |
| 436 | + |
| 437 | + if (when == WhenKey.Exists) |
| 438 | + { |
| 439 | + res = connection.CreateAndEval(nameof(Scripts.ReplaceHashIfExists), new[] { id }, argsList.ToArray()); |
| 440 | + } |
| 441 | + else if (when == WhenKey.NotExists) |
| 442 | + { |
| 443 | + res = connection.CreateAndEval(nameof(Scripts.HsetIfNotExists), new[] { id }, argsList.ToArray()); |
| 444 | + } |
| 445 | + |
| 446 | + return res == 1 ? id : null; |
| 447 | + } |
| 448 | + |
| 449 | + return connection.JsonSet(id, "$", obj, when, timespan) ? id : null; |
| 450 | + } |
| 451 | + |
| 452 | + /// <summary> |
| 453 | + /// Serializes an object to either hash or json (depending on how it's decorated, and saves it to redis conditionally based on the WhenKey, |
| 454 | + /// NOTE: <see cref="WhenKey.Exists"/> will replace the object in redis if it exists. |
| 455 | + /// </summary> |
| 456 | + /// <param name="connection">The connection to redis.</param> |
| 457 | + /// <param name="obj">The object to save.</param> |
| 458 | + /// <param name="when">The condition for when to set the object.</param> |
| 459 | + /// <param name="timespan">The length of time before the key expires.</param> |
| 460 | + /// <returns>the key for the object, null if nothing was set.</returns> |
| 461 | + public static async Task<string?> SetAsync(this IRedisConnection connection, object obj, WhenKey when, TimeSpan? timespan = null) |
| 462 | + { |
| 463 | + var id = obj.SetId(); |
| 464 | + var type = obj.GetType(); |
| 465 | + |
| 466 | + if (Attribute.GetCustomAttribute(type, typeof(DocumentAttribute)) is not DocumentAttribute attr || attr.StorageType == StorageType.Hash) |
| 467 | + { |
| 468 | + if (when == WhenKey.Always) |
| 469 | + { |
| 470 | + if (timespan.HasValue) |
| 471 | + { |
| 472 | + return await connection.SetAsync(obj, timespan.Value); |
| 473 | + } |
| 474 | + |
| 475 | + return await connection.SetAsync(obj); |
| 476 | + } |
| 477 | + |
| 478 | + var kvps = obj.BuildHashSet(); |
| 479 | + var argsList = new List<string>(); |
| 480 | + int? res = null; |
| 481 | + argsList.Add(timespan != null ? ((long)timespan.Value.TotalMilliseconds).ToString() : "-1"); |
| 482 | + foreach (var kvp in kvps) |
| 483 | + { |
| 484 | + argsList.Add(kvp.Key); |
| 485 | + argsList.Add(kvp.Value); |
| 486 | + } |
| 487 | + |
| 488 | + if (when == WhenKey.Exists) |
| 489 | + { |
| 490 | + res = await connection.CreateAndEvalAsync(nameof(Scripts.ReplaceHashIfExists), new[] { id }, argsList.ToArray()); |
| 491 | + } |
| 492 | + else if (when == WhenKey.NotExists) |
| 493 | + { |
| 494 | + res = await connection.CreateAndEvalAsync(nameof(Scripts.HsetIfNotExists), new[] { id }, argsList.ToArray()); |
| 495 | + } |
| 496 | + |
| 497 | + return res == 1 ? id : null; |
| 498 | + } |
| 499 | + |
| 500 | + return await connection.JsonSetAsync(id, "$", obj, when, timespan) ? id : null; |
| 501 | + } |
| 502 | + |
318 | 503 | /// <summary>
|
319 | 504 | /// Serializes an object to either hash or json (depending on how it's decorated), and saves it in redis.
|
320 | 505 | /// </summary>
|
|
0 commit comments