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

Commit

Permalink
Add support for Update and Insert filters
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Feb 16, 2014
1 parent 5daf6bd commit 9ac5f01
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/ServiceStack.OrmLite/Expressions/WriteExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public static int UpdateOnly<T>(this IDbCommand dbCmd, T model, Func<SqlExpressi
/// </summary>
public static int UpdateOnly<T>(this IDbCommand dbCmd, T model, SqlExpression<T> onlyFields)
{
if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, model);

var fieldsToUpdate = onlyFields.UpdateFields.Count == 0
? onlyFields.GetAllFields()
: onlyFields.UpdateFields;
Expand Down Expand Up @@ -79,6 +82,9 @@ public static int UpdateOnly<T>(this IDbCommand dbCmd, T model, SqlExpression<T>
/// </summary>
public static int UpdateNonDefaults<T>(this IDbCommand dbCmd, T item, Expression<Func<T, bool>> obj)
{
if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, item);

var ev = OrmLiteConfig.DialectProvider.SqlExpression<T>();
ev.Where(obj);
var sql = ev.ToUpdateStatement(item, excludeDefaults: true);
Expand All @@ -93,6 +99,9 @@ public static int UpdateNonDefaults<T>(this IDbCommand dbCmd, T item, Expression
/// </summary>
public static int Update<T>(this IDbCommand dbCmd, T item, Expression<Func<T, bool>> expression)
{
if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, item);

var ev = OrmLiteConfig.DialectProvider.SqlExpression<T>();
ev.Where(expression);
var sql = ev.ToUpdateStatement(item);
Expand Down Expand Up @@ -191,6 +200,9 @@ public static void InsertOnly<T>(this IDbCommand dbCmd, T obj, Func<SqlExpressio
/// </summary>
public static void InsertOnly<T>(this IDbCommand dbCmd, T obj, SqlExpression<T> onlyFields)
{
if (OrmLiteConfig.InsertFilter != null)
OrmLiteConfig.InsertFilter(dbCmd, obj);

var sql = OrmLiteConfig.DialectProvider.ToInsertRowStatement(dbCmd, obj, onlyFields.InsertFields);
dbCmd.ExecuteSql(sql);
}
Expand Down
3 changes: 3 additions & 0 deletions src/ServiceStack.OrmLite/OrmLiteConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,8 @@ public static IDbConnection ToDbConnection(this string dbConnectionStringOrFileP
var dbConn = dialectProvider.CreateConnection(dbConnectionStringOrFilePath, options: null);
return dbConn;
}

public static Action<IDbCommand, object> InsertFilter { get; set; }
public static Action<IDbCommand, object> UpdateFilter { get; set; }
}
}
24 changes: 24 additions & 0 deletions src/ServiceStack.OrmLite/OrmLiteWriteExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,9 @@ private static int TryGuessColumnIndex(string fieldName, IDataReader dataReader)

internal static int Update<T>(this IDbCommand dbCmd, T obj)
{
if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, obj);

OrmLiteConfig.DialectProvider.PrepareParameterizedUpdateStatement<T>(dbCmd);

OrmLiteConfig.DialectProvider.SetParameterValues<T>(dbCmd, obj);
Expand Down Expand Up @@ -364,6 +367,9 @@ internal static int UpdateAll<T>(this IDbCommand dbCmd, IEnumerable<T> objs)

foreach (var obj in objs)
{
if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, obj);

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

count += dbCmd.ExecNonQuery();
Expand Down Expand Up @@ -501,6 +507,9 @@ internal static int DeleteFmt(this IDbCommand dbCmd, Type tableType, string sqlF

internal static long Insert<T>(this IDbCommand dbCmd, T obj, bool selectIdentity = false)
{
if (OrmLiteConfig.InsertFilter != null)
OrmLiteConfig.InsertFilter(dbCmd, obj);

OrmLiteConfig.DialectProvider.PrepareParameterizedInsertStatement<T>(dbCmd);

OrmLiteConfig.DialectProvider.SetParameterValues<T>(dbCmd, obj);
Expand Down Expand Up @@ -531,6 +540,9 @@ internal static void InsertAll<T>(this IDbCommand dbCmd, IEnumerable<T> objs)

foreach (var obj in objs)
{
if (OrmLiteConfig.InsertFilter != null)
OrmLiteConfig.InsertFilter(dbCmd, obj);

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

dbCmd.ExecNonQuery();
Expand Down Expand Up @@ -566,11 +578,17 @@ internal static bool Save<T>(this IDbCommand dbCmd, T obj)
}
else
{
if (OrmLiteConfig.InsertFilter != null)
OrmLiteConfig.InsertFilter(dbCmd, obj);

dbCmd.Insert(obj);
}
return true;
}

if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, obj);

dbCmd.Update(obj);
return false;
}
Expand Down Expand Up @@ -606,6 +624,9 @@ internal static int SaveAll<T>(this IDbCommand dbCmd, IEnumerable<T> objs)
var id = row.GetId();
if (id != defaultIdValue && existingRowsMap.ContainsKey(id))
{
if (OrmLiteConfig.UpdateFilter != null)
OrmLiteConfig.UpdateFilter(dbCmd, row);

dbCmd.Update(row);
}
else
Expand All @@ -618,6 +639,9 @@ internal static int SaveAll<T>(this IDbCommand dbCmd, IEnumerable<T> objs)
}
else
{
if (OrmLiteConfig.InsertFilter != null)
OrmLiteConfig.InsertFilter(dbCmd, row);

dbCmd.Insert(row);
}

Expand Down
184 changes: 184 additions & 0 deletions tests/ServiceStack.OrmLite.Tests/OrmLiteFiltersTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
using System;
using NUnit.Framework;
using ServiceStack.DataAnnotations;

namespace ServiceStack.OrmLite.Tests
{
public interface IAudit
{
DateTime CreatedDate { get; set; }
DateTime ModifiedDate { get; set; }
string ModifiedBy { get; set; }
}

public class AuditTableA : IAudit
{
public int Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string ModifiedBy { get; set; }
}

public class AuditTableB : IAudit
{
[AutoIncrement]
public int Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime ModifiedDate { get; set; }
public string ModifiedBy { get; set; }
}

[TestFixture]
public class OrmLiteFiltersTests
: OrmLiteTestBase
{
[Test]
public void Does_call_Filters_on_insert_and_update()
{
var insertDate = new DateTime(2014, 1, 1);
var updateDate = new DateTime(2015, 1, 1);

OrmLiteConfig.InsertFilter = (dbCmd, row) =>
{
var auditRow = row as IAudit;
if (auditRow != null)
{
auditRow.CreatedDate = auditRow.ModifiedDate = insertDate;
}
};

OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
{
var auditRow = row as IAudit;
if (auditRow != null)
{
auditRow.ModifiedDate = updateDate;
}
};

using (var db = OpenDbConnection())
{
db.DropAndCreateTable<AuditTableA>();
db.DropAndCreateTable<AuditTableB>();

var idA = db.Insert(new AuditTableA(), selectIdentity: true);
var idB = db.Insert(new AuditTableB(), selectIdentity: true);

var insertRowA = db.SingleById<AuditTableA>(idA);
var insertRowB = db.SingleById<AuditTableB>(idB);

Assert.That(insertRowA.CreatedDate, Is.EqualTo(insertDate));
Assert.That(insertRowA.ModifiedDate, Is.EqualTo(insertDate));

Assert.That(insertRowB.CreatedDate, Is.EqualTo(insertDate));
Assert.That(insertRowB.ModifiedDate, Is.EqualTo(insertDate));

insertRowA.ModifiedBy = "Updated";
db.Update(insertRowA);

insertRowA = db.SingleById<AuditTableA>(idA);
Assert.That(insertRowA.ModifiedDate, Is.EqualTo(updateDate));
}

OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = null;
}

[Test]
public void Does_call_Filters_on_Save()
{
var insertDate = new DateTime(2014, 1, 1);
var updateDate = new DateTime(2015, 1, 1);

OrmLiteConfig.InsertFilter = (dbCmd, row) =>
{
var auditRow = row as IAudit;
if (auditRow != null)
{
auditRow.CreatedDate = auditRow.ModifiedDate = insertDate;
}
};

OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
{
var auditRow = row as IAudit;
if (auditRow != null)
{
auditRow.ModifiedDate = updateDate;
}
};

using (var db = OpenDbConnection())
{
db.DropAndCreateTable<AuditTableA>();
db.DropAndCreateTable<AuditTableB>();

var a = new AuditTableA();
var b = new AuditTableB();
db.Save(a);
db.Save(b);

var insertRowA = db.SingleById<AuditTableA>(a.Id);
var insertRowB = db.SingleById<AuditTableB>(b.Id);

Assert.That(insertRowA.CreatedDate, Is.EqualTo(insertDate));
Assert.That(insertRowA.ModifiedDate, Is.EqualTo(insertDate));

Assert.That(insertRowB.CreatedDate, Is.EqualTo(insertDate));
Assert.That(insertRowB.ModifiedDate, Is.EqualTo(insertDate));

a.ModifiedBy = "Updated";
db.Update(a);

a = db.SingleById<AuditTableA>(a.Id);
Assert.That(a.ModifiedDate, Is.EqualTo(updateDate));
}

OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = null;
}

[Test]
public void Exceptions_in_filters_prevents_insert_and_update()
{
OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
{
var auditRow = row as IAudit;
if (auditRow != null)
{
if (auditRow.ModifiedBy == null)
throw new ArgumentNullException("ModifiedBy");
}
};

using (var db = OpenDbConnection())
{
db.DropAndCreateTable<AuditTableA>();
db.DropAndCreateTable<AuditTableB>();

try
{
db.Insert(new AuditTableA());
Assert.Fail("Should throw");
}
catch (ArgumentNullException) {}
Assert.That(db.Count<AuditTableA>(), Is.EqualTo(0));

var a = new AuditTableA {ModifiedBy = "Me!"};
db.Insert(a);

a.ModifiedBy = null;
try
{
db.Update(a);
Assert.Fail("Should throw");
}
catch (ArgumentNullException) { }

a.ModifiedBy = "Me2!";
db.Update(a);
}

OrmLiteConfig.InsertFilter = OrmLiteConfig.UpdateFilter = null;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<Compile Include="LicenseUsageTests.cs" />
<Compile Include="LoadReferencesTests.cs" />
<Compile Include="MockAllApiTests.cs" />
<Compile Include="OrmLiteFiltersTests.cs" />
<Compile Include="StringSerializerTests.cs" />
<Compile Include="TypeDescriptorMetadataTests.cs" />
<Compile Include="Shared\ApiUtilExtensions.cs" />
Expand Down

0 comments on commit 9ac5f01

Please sign in to comment.