Skip to content

Commit 456c63f

Browse files
authored
adding certain async collection operations (#89)
* adding certain async collection operations * differentiating sync version for collection.Delete and Collection.update
1 parent 0037ab6 commit 456c63f

File tree

8 files changed

+848
-4
lines changed

8 files changed

+848
-4
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
3+
namespace Redis.OM.Modeling
4+
{
5+
/// <summary>
6+
/// utility functions for document attribute class.
7+
/// </summary>
8+
internal static class DocumentAttributeExtensions
9+
{
10+
/// <summary>
11+
/// Get's the index name for the attribute and type.
12+
/// </summary>
13+
/// <param name="attr">The document attribute.</param>
14+
/// <param name="type">The type.</param>
15+
/// <returns>The index name.</returns>
16+
internal static string GetIndexName(this DocumentAttribute attr, Type type) => string.IsNullOrEmpty(attr.IndexName) ? $"{type.Name.ToLower()}-idx" : attr.IndexName!;
17+
}
18+
}

src/Redis.OM/RediSearchCommands.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,5 +177,17 @@ internal static RedisReply SearchRawResult(this IRedisConnection connection, Red
177177
var args = query.SerializeQuery();
178178
return connection.Execute("FT.SEARCH", args);
179179
}
180+
181+
/// <summary>
182+
/// Search redis with the given query.
183+
/// </summary>
184+
/// <param name="connection">the connection to redis.</param>
185+
/// <param name="query">the query to use in the search.</param>
186+
/// <returns>a Redis reply.</returns>
187+
internal static Task<RedisReply> SearchRawResultAsync(this IRedisConnection connection, RedisQuery query)
188+
{
189+
var args = query.SerializeQuery();
190+
return connection.ExecuteAsync("FT.SEARCH", args);
191+
}
180192
}
181193
}

src/Redis.OM/RedisCommands.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,36 @@ public static async Task<IDictionary<string, string>> HGetAllAsync(this IRedisCo
372372
/// <returns>the status.</returns>
373373
public static async Task<string> UnlinkAsync(this IRedisConnection connection, string key) => await connection.ExecuteAsync("UNLINK", key);
374374

375+
/// <summary>
376+
/// Unlinks the key and then adds an updated value of it.
377+
/// </summary>
378+
/// <param name="connection">The connection to redis.</param>
379+
/// <param name="key">The key.</param>
380+
/// <param name="value">The value.</param>
381+
/// <param name="storageType">The storage type of the value.</param>
382+
/// <typeparam name="T">The type of the value.</typeparam>
383+
internal static void UnlinkAndSet<T>(this IRedisConnection connection, string key, T value, StorageType storageType)
384+
{
385+
_ = value ?? throw new ArgumentNullException(nameof(value));
386+
if (storageType == StorageType.Json)
387+
{
388+
connection.CreateAndEval(nameof(Scripts.UnlinkAndSendJson), new[] { key }, new[] { JsonSerializer.Serialize(value, Options) });
389+
}
390+
else
391+
{
392+
var hash = value.BuildHashSet();
393+
var args = new List<string>((hash.Keys.Count * 2) + 1);
394+
args.Add(hash.Keys.Count.ToString());
395+
foreach (var pair in hash)
396+
{
397+
args.Add(pair.Key);
398+
args.Add(pair.Value);
399+
}
400+
401+
connection.CreateAndEval(nameof(Scripts.UnlinkAndSetHash), new[] { key }, args.ToArray());
402+
}
403+
}
404+
375405
/// <summary>
376406
/// Unlinks the key and then adds an updated value of it.
377407
/// </summary>
@@ -381,7 +411,7 @@ public static async Task<IDictionary<string, string>> HGetAllAsync(this IRedisCo
381411
/// <param name="storageType">The storage type of the value.</param>
382412
/// <typeparam name="T">The type of the value.</typeparam>
383413
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
384-
internal static async Task UnlinkAndSet<T>(this IRedisConnection connection, string key, T value, StorageType storageType)
414+
internal static async Task UnlinkAndSetAsync<T>(this IRedisConnection connection, string key, T value, StorageType storageType)
385415
{
386416
_ = value ?? throw new ArgumentNullException(nameof(value));
387417
if (storageType == StorageType.Json)

src/Redis.OM/Searching/IRedisCollection.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,114 @@ public interface IRedisCollection<T> : IOrderedQueryable<T>, IAsyncEnumerable<T>
6969
/// <returns>Whether anything matching the expression was found.</returns>
7070
bool Any(Expression<Func<T, bool>> expression);
7171

72+
/// <summary>
73+
/// Updates the provided item in Redis. Document must have a property marked with the <see cref="RedisIdFieldAttribute"/>.
74+
/// </summary>
75+
/// <param name="item">The item to update.</param>
76+
void UpdateSync(T item);
77+
7278
/// <summary>
7379
/// Updates the provided item in Redis. Document must have a property marked with the <see cref="RedisIdFieldAttribute"/>.
7480
/// </summary>
7581
/// <param name="item">The item to update.</param>
7682
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
7783
Task Update(T item);
7884

85+
/// <summary>
86+
/// Deletes the item from Redis.
87+
/// </summary>
88+
/// <param name="item">The item to be deleted.</param>
89+
void DeleteSync(T item);
90+
7991
/// <summary>
8092
/// Deletes the item from Redis.
8193
/// </summary>
8294
/// <param name="item">The item to be deleted.</param>
8395
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
8496
Task Delete(T item);
97+
98+
/// <summary>
99+
/// Async method for enumerating the collection to a list.
100+
/// </summary>
101+
/// <returns>The enumerated collection as a list.</returns>
102+
Task<IList<T>> ToListAsync();
103+
104+
/// <summary>
105+
/// Retrieves the count of the collection async.
106+
/// </summary>
107+
/// <returns>The Collection's count.</returns>
108+
Task<int> CountAsync();
109+
110+
/// <summary>
111+
/// Retrieves the count of the collection async.
112+
/// </summary>
113+
/// <param name="expression">The predicate match.</param>
114+
/// <returns>The Collection's count.</returns>
115+
Task<int> CountAsync(Expression<Func<T, bool>> expression);
116+
117+
/// <summary>
118+
/// returns if there's any items in the colleciton.
119+
/// </summary>
120+
/// <returns>True if there are items present.</returns>
121+
Task<bool> AnyAsync();
122+
123+
/// <summary>
124+
/// returns if there's any items in the colleciton.
125+
/// </summary>
126+
/// <returns>True if there are items present.</returns>
127+
/// <param name="expression">The predicate match.</param>
128+
Task<bool> AnyAsync(Expression<Func<T, bool>> expression);
129+
130+
/// <summary>
131+
/// Returns the first item asynchronously.
132+
/// </summary>
133+
/// <returns>First or default result.</returns>
134+
Task<T> FirstAsync();
135+
136+
/// <summary>
137+
/// Returns the first item asynchronously.
138+
/// </summary>
139+
/// <param name="expression">The predicate match.</param>
140+
/// <returns>First or default result.</returns>
141+
Task<T> FirstAsync(Expression<Func<T, bool>> expression);
142+
143+
/// <summary>
144+
/// Returns the first or default asynchronously.
145+
/// </summary>
146+
/// <returns>First or default result.</returns>
147+
Task<T?> FirstOrDefaultAsync();
148+
149+
/// <summary>
150+
/// Returns the first or default asynchronously.
151+
/// </summary>
152+
/// <param name="expression">The predicate match.</param>
153+
/// <returns>First or default result.</returns>
154+
Task<T?> FirstOrDefaultAsync(Expression<Func<T, bool>> expression);
155+
156+
/// <summary>
157+
/// Returns a single record or throws a <see cref="InvalidOperationException"/> if the sequence is empty or contains more than 1 record.
158+
/// </summary>
159+
/// <returns>The single instance.</returns>
160+
Task<T> SingleAsync();
161+
162+
/// <summary>
163+
/// Returns a single record or throws a <see cref="InvalidOperationException"/> if the sequence is empty or contains more than 1 record.
164+
/// </summary>
165+
/// <param name="expression">The expression.</param>
166+
/// <returns>The single instance.</returns>
167+
Task<T> SingleAsync(Expression<Func<T, bool>> expression);
168+
169+
/// <summary>
170+
/// Returns a single record or the default if there are none, or more than 1.
171+
/// </summary>
172+
/// <returns>The single instance.</returns>
173+
Task<T?> SingleOrDefaultAsync();
174+
175+
/// <summary>
176+
/// Returns a single record or the default if there are none, or more than 1.
177+
/// </summary>
178+
/// <param name="expression">The expression.</param>
179+
/// <returns>The single instance.</returns>
180+
Task<T?> SingleOrDefaultAsync(Expression<Func<T, bool>> expression);
85181
}
86182
}

0 commit comments

Comments
 (0)