Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit e818b16

Browse files
committed
Add commandFilter support for async Delete APIs as well
1 parent ac28db5 commit e818b16

9 files changed

+93
-48
lines changed

src/ServiceStack.OrmLite/Async/OrmLiteWriteCommandExtensionsAsync.cs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,25 @@ internal static class OrmLiteWriteCommandExtensionsAsync
1919
{
2020
internal static ILog Log = LogManager.GetLogger(typeof(OrmLiteWriteCommandExtensionsAsync));
2121

22-
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, IEnumerable<IDbDataParameter> sqlParams, CancellationToken token)
22+
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, IEnumerable<IDbDataParameter> sqlParams, CancellationToken token) =>
23+
dbCmd.SetParameters(sqlParams).ExecuteSqlAsync(sql, (Action<IDbCommand>) null, token);
24+
25+
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, IEnumerable<IDbDataParameter> sqlParams,
26+
Action<IDbCommand> commandFilter, CancellationToken token)
2327
{
24-
return dbCmd.SetParameters(sqlParams).ExecuteSqlAsync(sql, token);
28+
return dbCmd.SetParameters(sqlParams).ExecuteSqlAsync(sql, commandFilter, token);
2529
}
2630

27-
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, CancellationToken token)
31+
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, CancellationToken token) =>
32+
dbCmd.ExecuteSqlAsync(sql,(Action<IDbCommand>)null, token);
33+
34+
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql,
35+
Action<IDbCommand> commandFilter, CancellationToken token)
2836
{
2937
dbCmd.CommandText = sql;
3038

39+
commandFilter?.Invoke(dbCmd);
40+
3141
if (Log.IsDebugEnabled)
3242
Log.DebugCommand(dbCmd);
3343

@@ -39,13 +49,19 @@ internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, Can
3949
return dbCmd.GetDialectProvider().ExecuteNonQueryAsync(dbCmd, token);
4050
}
4151

42-
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token)
52+
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, object anonType, CancellationToken token) =>
53+
dbCmd.ExecuteSqlAsync(sql, anonType, null, token);
54+
55+
internal static Task<int> ExecuteSqlAsync(this IDbCommand dbCmd, string sql, object anonType,
56+
Action<IDbCommand> commandFilter, CancellationToken token)
4357
{
4458
if (anonType != null)
4559
dbCmd.SetParameters(anonType.ToObjectDictionary(), excludeDefaults: false, sql:ref sql);
4660

4761
dbCmd.CommandText = sql;
4862

63+
commandFilter?.Invoke(dbCmd);
64+
4965
if (Log.IsDebugEnabled)
5066
Log.DebugCommand(dbCmd);
5167

@@ -122,7 +138,8 @@ internal static async Task<int> UpdateAllAsync<T>(this IDbCommand dbCmd, IEnumer
122138
OrmLiteConfig.UpdateFilter?.Invoke(dbCmd, obj);
123139

124140
dialectProvider.SetParameterValues<T>(dbCmd, obj);
125-
commandFilter?.Invoke(dbCmd);
141+
142+
commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once
126143
commandFilter = null;
127144

128145
var rowsUpdated = await dbCmd.ExecNonQueryAsync(token);
@@ -192,10 +209,11 @@ internal static Task<int> DeleteNonDefaultsAsync<T>(this IDbCommand dbCmd, Cance
192209
if (filters.Length == 0)
193210
return TaskResult.Zero;
194211

195-
return DeleteAllAsync(dbCmd, filters, o => o.AllFieldsMap<T>().NonDefaultsOnly(), token);
212+
return DeleteAllAsync(dbCmd, filters, o => o.AllFieldsMap<T>().NonDefaultsOnly(), token:token);
196213
}
197214

198-
private static async Task<int> DeleteAllAsync<T>(IDbCommand dbCmd, IEnumerable<T> objs, Func<object, Dictionary<string, object>> fieldValuesFn = null, CancellationToken token=default(CancellationToken))
215+
private static async Task<int> DeleteAllAsync<T>(IDbCommand dbCmd, IEnumerable<T> objs, Func<object, Dictionary<string, object>> fieldValuesFn = null,
216+
Action<IDbCommand> commandFilter=null, CancellationToken token=default)
199217
{
200218
OrmLiteUtils.AssertNotAnonType<T>();
201219

@@ -218,6 +236,9 @@ private static async Task<int> DeleteAllAsync<T>(IDbCommand dbCmd, IEnumerable<T
218236
dialectProvider.PrepareParameterizedDeleteStatement<T>(dbCmd, fieldValues);
219237

220238
dialectProvider.SetParameterValues<T>(dbCmd, obj);
239+
240+
commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once
241+
commandFilter = null;
221242

222243
var rowsAffected = await dbCmd.ExecNonQueryAsync(token);
223244
count += rowsAffected;
@@ -228,34 +249,37 @@ private static async Task<int> DeleteAllAsync<T>(IDbCommand dbCmd, IEnumerable<T
228249
return count;
229250
}
230251

231-
internal static Task<int> DeleteByIdAsync<T>(this IDbCommand dbCmd, object id, CancellationToken token)
252+
internal static Task<int> DeleteByIdAsync<T>(this IDbCommand dbCmd, object id,
253+
Action<IDbCommand> commandFilter, CancellationToken token)
232254
{
233255
OrmLiteUtils.AssertNotAnonType<T>();
234256

235257
var sql = dbCmd.DeleteByIdSql<T>(id);
236-
return dbCmd.ExecuteSqlAsync(sql, token);
258+
return dbCmd.ExecuteSqlAsync(sql, commandFilter, token);
237259
}
238260

239-
internal static async Task DeleteByIdAsync<T>(this IDbCommand dbCmd, object id, ulong rowVersion, CancellationToken token)
261+
internal static async Task DeleteByIdAsync<T>(this IDbCommand dbCmd, object id, ulong rowVersion,
262+
Action<IDbCommand> commandFilter, CancellationToken token)
240263
{
241264
OrmLiteUtils.AssertNotAnonType<T>();
242265

243266
var sql = dbCmd.DeleteByIdSql<T>(id, rowVersion);
244267

245-
var rowsAffected = await dbCmd.ExecuteSqlAsync(sql, token);
268+
var rowsAffected = await dbCmd.ExecuteSqlAsync(sql, commandFilter, token);
246269
if (rowsAffected == 0)
247270
throw new OptimisticConcurrencyException("The row was modified or deleted since the last read");
248271
}
249272

250-
internal static Task<int> DeleteByIdsAsync<T>(this IDbCommand dbCmd, IEnumerable idValues, CancellationToken token)
273+
internal static Task<int> DeleteByIdsAsync<T>(this IDbCommand dbCmd, IEnumerable idValues,
274+
Action<IDbCommand> commandFilter, CancellationToken token)
251275
{
252276
var sqlIn = dbCmd.SetIdsInSqlParams(idValues);
253277
if (string.IsNullOrEmpty(sqlIn))
254278
return TaskResult.Zero;
255279

256280
var sql = OrmLiteWriteCommandExtensions.GetDeleteByIdsSql<T>(sqlIn, dbCmd.GetDialectProvider());
257281

258-
return dbCmd.ExecuteSqlAsync(sql, token);
282+
return dbCmd.ExecuteSqlAsync(sql, commandFilter, token);
259283
}
260284

261285
internal static Task<int> DeleteAllAsync<T>(this IDbCommand dbCmd, CancellationToken token)
@@ -405,8 +429,6 @@ internal static async Task InsertAllAsync<T>(this IDbCommand dbCmd, IEnumerable<
405429

406430
dialectProvider.PrepareParameterizedInsertStatement<T>(dbCmd);
407431

408-
commandFilter?.Invoke(dbCmd);
409-
410432
using (dbTrans)
411433
{
412434
foreach (var obj in objs)
@@ -415,6 +437,9 @@ internal static async Task InsertAllAsync<T>(this IDbCommand dbCmd, IEnumerable<
415437

416438
dialectProvider.SetParameterValues<T>(dbCmd, obj);
417439

440+
commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once
441+
commandFilter = null;
442+
418443
await dbCmd.ExecNonQueryAsync(token);
419444
}
420445
dbTrans?.Commit();

src/ServiceStack.OrmLite/Async/WriteExpressionCommandExtensionsAsync.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,25 +205,28 @@ public static Task<int> InsertOnlyAsync<T>(this IDbCommand dbCmd, Expression<Fun
205205
return dbCmd.InitInsertOnly(insertFields).ExecNonQueryAsync(token);
206206
}
207207

208-
internal static Task<int> DeleteAsync<T>(this IDbCommand dbCmd, Expression<Func<T, bool>> where, CancellationToken token)
208+
internal static Task<int> DeleteAsync<T>(this IDbCommand dbCmd, Expression<Func<T, bool>> where,
209+
Action<IDbCommand> commandFilter, CancellationToken token)
209210
{
210211
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
211212
q.Where(where);
212-
return dbCmd.DeleteAsync(q, token);
213+
return dbCmd.DeleteAsync(q, commandFilter, token);
213214
}
214215

215-
internal static Task<int> DeleteAsync<T>(this IDbCommand dbCmd, SqlExpression<T> q, CancellationToken token)
216+
internal static Task<int> DeleteAsync<T>(this IDbCommand dbCmd, SqlExpression<T> q,
217+
Action<IDbCommand> commandFilter, CancellationToken token)
216218
{
217219
var sql = q.ToDeleteRowStatement();
218-
return dbCmd.ExecuteSqlAsync(sql, q.Params, token);
220+
return dbCmd.ExecuteSqlAsync(sql, q.Params, commandFilter, token);
219221
}
220222

221-
internal static Task<int> DeleteWhereAsync<T>(this IDbCommand dbCmd, string whereFilter, object[] whereParams, CancellationToken token)
223+
internal static Task<int> DeleteWhereAsync<T>(this IDbCommand dbCmd, string whereFilter, object[] whereParams,
224+
Action<IDbCommand> commandFilter, CancellationToken token)
222225
{
223226
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
224227
q.Where(whereFilter, whereParams);
225228
var sql = q.ToDeleteRowStatement();
226-
return dbCmd.ExecuteSqlAsync(sql, q.Params, token);
229+
return dbCmd.ExecuteSqlAsync(sql, q.Params, commandFilter, token);
227230
}
228231
}
229232
}

src/ServiceStack.OrmLite/Legacy/WriteExpressionCommandExtensionsAsyncLegacy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ internal static Task<int> UpdateFmtAsync(this IDbCommand dbCmd, string table, st
3636
[Obsolete("Use db.DeleteAsync(db.From<T>())")]
3737
internal static Task<int> DeleteAsync<T>(this IDbCommand dbCmd, Func<SqlExpression<T>, SqlExpression<T>> where, CancellationToken token)
3838
{
39-
return dbCmd.DeleteAsync(where(dbCmd.GetDialectProvider().SqlExpression<T>()), token);
39+
return dbCmd.DeleteAsync(where(dbCmd.GetDialectProvider().SqlExpression<T>()), null, token);
4040
}
4141

4242
internal static Task<int> DeleteFmtAsync<T>(this IDbCommand dbCmd, string where, CancellationToken token)

src/ServiceStack.OrmLite/OrmLiteUtils.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,9 @@ public static void AssertNotAnonType<T>()
987987

988988
if (typeof(T) == typeof(Dictionary<string,object>))
989989
throw new ArgumentException("T generic argument should be a Table but was typeof(Dictionary<string,object>)");
990+
991+
if (typeof(ISqlExpression).IsAssignableFrom(typeof(T)))
992+
throw new ArgumentException("T generic argument should be a Table but was an ISqlExpression");
990993
}
991994

992995
public static List<string> GetNonDefaultValueInsertFields<T>(this IOrmLiteDialectProvider dialectProvider, object obj)

src/ServiceStack.OrmLite/OrmLiteWriteApi.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public static int DeleteById<T>(this IDbConnection dbConn, object id, Action<IDb
280280

281281
/// <summary>
282282
/// Delete 1 row by the PrimaryKey where the rowVersion matches the optimistic concurrency field.
283-
/// Will throw <exception cref="OptimisticConcurrencyException">RowModefiedExeption</exception> if the
283+
/// Will throw <exception cref="OptimisticConcurrencyException">RowModifiedException</exception> if the
284284
/// row does not exist or has a different row version.
285285
/// E.g: <para>db.DeleteById&lt;Person&gt;(1)</para>
286286
/// </summary>

src/ServiceStack.OrmLite/OrmLiteWriteApiAsync.cs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,8 @@ public static Task<int> UpdateAllAsync<T>(this IDbConnection dbConn, IEnumerable
196196
/// <para>db.DeleteAsync&lt;Person&gt;(new { FirstName = "Jimi", Age = 27 })</para>
197197
/// </summary>
198198
/// <returns>number of rows deleted</returns>
199-
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, object anonFilter, CancellationToken token = default)
199+
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, object anonFilter,
200+
Action<IDbCommand> commandFilter = null, CancellationToken token = default)
200201
{
201202
return dbConn.Exec(dbCmd => dbCmd.DeleteAsync<T>(anonFilter, token));
202203
}
@@ -206,7 +207,8 @@ public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, object anonFil
206207
/// <para>db.DeleteAsync&lt;Person&gt;(new Dictionary&lt;string,object&gt; { ["FirstName"] = "Jimi", ["Age"] = 27 })</para>
207208
/// </summary>
208209
/// <returns>number of rows deleted</returns>
209-
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, Dictionary<string, object> filters, CancellationToken token = default)
210+
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, Dictionary<string, object> filters,
211+
Action<IDbCommand> commandFilter = null, CancellationToken token = default)
210212
{
211213
return dbConn.Exec(dbCmd => dbCmd.DeleteAsync<T>(filters, token));
212214
}
@@ -216,7 +218,8 @@ public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, Dictionary<str
216218
/// <para>db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 })</para>
217219
/// </summary>
218220
/// <returns>number of rows deleted</returns>
219-
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, T allFieldsFilter, CancellationToken token = default)
221+
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, T allFieldsFilter,
222+
Action<IDbCommand> commandFilter = null, CancellationToken token = default)
220223
{
221224
return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(allFieldsFilter, token));
222225
}
@@ -225,11 +228,13 @@ public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, T allFieldsFil
225228
/// Delete 1 or more rows in a transaction using all fields in the commandFilter. E.g:
226229
/// <para>db.DeleteAsync(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 })</para>
227230
/// </summary>
228-
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, CancellationToken token = default, params T[] allFieldsFilters)
231+
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn,
232+
Action<IDbCommand> commandFilter = null, CancellationToken token = default, params T[] allFieldsFilters)
229233
{
230234
return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(token, allFieldsFilters));
231235
}
232-
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn, params T[] allFieldsFilters)
236+
public static Task<int> DeleteAsync<T>(this IDbConnection dbConn,
237+
Action<IDbCommand> commandFilter = null, params T[] allFieldsFilters)
233238
{
234239
return dbConn.Exec(dbCmd => dbCmd.DeleteAsync(default, allFieldsFilters));
235240
}
@@ -256,38 +261,41 @@ public static Task<int> DeleteNonDefaultsAsync<T>(this IDbConnection dbConn, Can
256261
}
257262
public static Task<int> DeleteNonDefaultsAsync<T>(this IDbConnection dbConn, params T[] nonDefaultsFilters)
258263
{
259-
return dbConn.Exec(dbCmd => dbCmd.DeleteNonDefaultsAsync(default(CancellationToken), nonDefaultsFilters));
264+
return dbConn.Exec(dbCmd => dbCmd.DeleteNonDefaultsAsync(default, nonDefaultsFilters));
260265
}
261266

262267
/// <summary>
263268
/// Delete 1 row by the PrimaryKey. E.g:
264269
/// <para>db.DeleteByIdAsync&lt;Person&gt;(1)</para>
265270
/// </summary>
266271
/// <returns>number of rows deleted</returns>
267-
public static Task<int> DeleteByIdAsync<T>(this IDbConnection dbConn, object id, CancellationToken token = default)
272+
public static Task<int> DeleteByIdAsync<T>(this IDbConnection dbConn, object id,
273+
Action<IDbCommand> commandFilter = null, CancellationToken token = default)
268274
{
269-
return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync<T>(id, token));
275+
return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync<T>(id, commandFilter, token));
270276
}
271277

272278
/// <summary>
273279
/// Delete 1 row by the PrimaryKey where the rowVersion matches the optimistic concurrency field.
274-
/// Will throw <exception cref="OptimisticConcurrencyException">RowModefiedExeption</exception> if the
280+
/// Will throw <exception cref="OptimisticConcurrencyException">RowModifiedException</exception> if the
275281
/// row does not exist or has a different row version.
276282
/// E.g: <para>db.DeleteByIdAsync&lt;Person&gt;(1)</para>
277283
/// </summary>
278-
public static Task DeleteByIdAsync<T>(this IDbConnection dbConn, object id, ulong rowVersion, CancellationToken token = default)
284+
public static Task DeleteByIdAsync<T>(this IDbConnection dbConn, object id, ulong rowVersion,
285+
Action<IDbCommand> commandFilter = null, CancellationToken token = default)
279286
{
280-
return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync<T>(id, rowVersion, token));
287+
return dbConn.Exec(dbCmd => dbCmd.DeleteByIdAsync<T>(id, rowVersion, commandFilter, token));
281288
}
282289

283290
/// <summary>
284291
/// Delete all rows identified by the PrimaryKeys. E.g:
285292
/// <para>db.DeleteByIdsAsync&lt;Person&gt;(new[] { 1, 2, 3 })</para>
286293
/// </summary>
287294
/// <returns>number of rows deleted</returns>
288-
public static Task<int> DeleteByIdsAsync<T>(this IDbConnection dbConn, IEnumerable idValues, CancellationToken token = default)
295+
public static Task<int> DeleteByIdsAsync<T>(this IDbConnection dbConn, IEnumerable idValues,
296+
Action<IDbCommand> commandFilter = null, CancellationToken token = default)
289297
{
290-
return dbConn.Exec(dbCmd => dbCmd.DeleteByIdsAsync<T>(idValues, token));
298+
return dbConn.Exec(dbCmd => dbCmd.DeleteByIdsAsync<T>(idValues, commandFilter, token));
291299
}
292300

293301
/// <summary>

src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,9 @@ internal static int UpdateAll<T>(this IDbCommand dbCmd, IEnumerable<T> objs, Act
486486

487487
dialectProvider.SetParameterValues<T>(dbCmd, obj);
488488

489-
commandFilter?.Invoke(dbCmd);
489+
commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once
490490
commandFilter = null;
491+
491492
var rowsUpdated = dbCmd.ExecNonQuery();
492493
if (hadRowVersion && rowsUpdated == 0)
493494
throw new OptimisticConcurrencyException();
@@ -559,7 +560,8 @@ internal static int DeleteNonDefaults<T>(this IDbCommand dbCmd, T[] filters)
559560
return DeleteAll(dbCmd, filters, o => o.AllFieldsMap<T>().NonDefaultsOnly());
560561
}
561562

562-
private static int DeleteAll<T>(IDbCommand dbCmd, IEnumerable<T> objs, Func<object,Dictionary<string,object>> fieldValuesFn=null, Action<IDbCommand> commandFilter = null)
563+
private static int DeleteAll<T>(IDbCommand dbCmd, IEnumerable<T> objs,
564+
Func<object,Dictionary<string,object>> fieldValuesFn, Action<IDbCommand> commandFilter = null)
563565
{
564566
OrmLiteUtils.AssertNotAnonType<T>();
565567

@@ -583,7 +585,7 @@ private static int DeleteAll<T>(IDbCommand dbCmd, IEnumerable<T> objs, Func<obje
583585

584586
dialectProvider.SetParameterValues<T>(dbCmd, obj);
585587

586-
commandFilter?.Invoke(dbCmd);
588+
commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once
587589
commandFilter = null;
588590

589591
count += dbCmd.ExecNonQuery();
@@ -864,13 +866,14 @@ internal static void InsertAll<T>(this IDbCommand dbCmd, IEnumerable<T> objs, Ac
864866

865867
dialectProvider.PrepareParameterizedInsertStatement<T>(dbCmd);
866868

867-
commandFilter?.Invoke(dbCmd);
868-
869869
foreach (var obj in objs)
870870
{
871871
OrmLiteConfig.InsertFilter?.Invoke(dbCmd, obj);
872872
dialectProvider.SetParameterValues<T>(dbCmd, obj);
873873

874+
commandFilter?.Invoke(dbCmd); //filters can augment SQL & only should be invoked once
875+
commandFilter = null;
876+
874877
try
875878
{
876879
dbCmd.ExecNonQuery();

0 commit comments

Comments
 (0)