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

Commit e77cde8

Browse files
committed
Extended OrmLiteResultsFilter to filter on IDbCommand.
OrmLiteResultsFilter now has a SqlCommandFilter action similar to SqlFilter. This allows you to filter on the actual SqlCommand instead of just the sql statement itself. This can be useful especially if you are trying to troubleshoot the values that are being inserted as parameters. I created a basic result filter similar to the existing CaptureSqlFilter called CaptureSqlCommandFilter. This attempts to preserve the command data as a new SqlCommandDetails object with parameter values stored in a Dictionary along with the Sql string. I created unit tests for the SqlCommandFilter similar to those for SqlFilter and added similar checks for existing tests that use SqlFilter. -- This is a product of me digging into OrmLite to discover why SqlGeography types weren't being inserted into the database. I've build this SqlCommandFilter as an alternative to the debugging that I did to track down my issue, hopefully this will help someone in the future figuring out exactly what values are being added to the IDbCommand parameters.
1 parent 7557710 commit e77cde8

File tree

4 files changed

+362
-3
lines changed

4 files changed

+362
-3
lines changed

src/ServiceStack.OrmLite/OrmLiteResultsFilter.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ public class OrmLiteResultsFilter : IOrmLiteResultsFilter, IDisposable
6868
public Func<IDbCommand, long> LastInsertIdFn { get; set; }
6969

7070
public Action<string> SqlFilter { get; set; }
71+
public Action<IDbCommand> SqlCommandFilter { get; set; }
72+
7173
public bool PrintSql { get; set; }
7274

7375
private readonly IOrmLiteResultsFilter previousFilter;
@@ -87,6 +89,11 @@ private void Filter(IDbCommand dbCmd)
8789
SqlFilter(dbCmd.CommandText);
8890
}
8991

92+
if (SqlCommandFilter != null)
93+
{
94+
SqlCommandFilter(dbCmd);
95+
}
96+
9097
if (PrintSql)
9198
{
9299
Console.WriteLine(dbCmd.CommandText);
@@ -326,4 +333,42 @@ private void CaptureSql(string sql)
326333

327334
public List<string> SqlStatements { get; set; }
328335
}
336+
337+
public class CaptureSqlCommandFilter : OrmLiteResultsFilter
338+
{
339+
public CaptureSqlCommandFilter()
340+
{
341+
SqlCommandFilter = CaptureSqlCommand;
342+
SqlCommandHistory = new List<SqlCommandDetails>();
343+
}
344+
345+
private void CaptureSqlCommand(IDbCommand command)
346+
{
347+
SqlCommandHistory.Add(new SqlCommandDetails(command));
348+
}
349+
350+
public List<SqlCommandDetails> SqlCommandHistory { get; set; }
351+
}
352+
353+
public class SqlCommandDetails
354+
{
355+
public SqlCommandDetails(IDbCommand command)
356+
{
357+
if (command != null)
358+
{
359+
Sql = command.CommandText;
360+
if(command.Parameters.Count > 0)
361+
{
362+
Parameters = new Dictionary<string, object>();
363+
364+
foreach (IDataParameter parameter in command.Parameters)
365+
if (!Parameters.ContainsKey(parameter.ParameterName))
366+
Parameters.Add(parameter.ParameterName, parameter.Value);
367+
}
368+
}
369+
}
370+
371+
public string Sql { get; set; }
372+
public Dictionary<string, object> Parameters { get; set; }
373+
}
329374
}
Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using NUnit.Framework;
4+
using ServiceStack.OrmLite.Tests.Shared;
5+
using ServiceStack.Text;
6+
7+
namespace ServiceStack.OrmLite.Tests
8+
{
9+
[TestFixture]
10+
public class CaptureSqlCommandFilterTests
11+
: OrmLiteTestBase
12+
{
13+
[Test]
14+
public void Can_capture_command_each_type_of_API()
15+
{
16+
using (var captured = new CaptureSqlCommandFilter())
17+
using (var db = OpenDbConnection())
18+
{
19+
db.CreateTable<Person>();
20+
db.Select<Person>(x => x.Age > 40);
21+
db.Single<Person>(x => x.Age == 42);
22+
db.Count<Person>(x => x.Age < 50);
23+
db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse" });
24+
db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix" });
25+
db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
26+
db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age",
27+
new { age = 50 });
28+
db.SqlList<Person>("exec sp_name @firstName, @age",
29+
new { firstName = "aName", age = 1 });
30+
db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}"
31+
.SqlFmt("WaterHouse", 7));
32+
33+
captured.SqlCommandHistory.PrintDump();
34+
}
35+
}
36+
37+
[Test]
38+
public void Can_capture_command_CreateTable_APIs()
39+
{
40+
using (var db = OpenDbConnection())
41+
{
42+
db.DropTable<Person>();
43+
}
44+
45+
using (var captured = new CaptureSqlCommandFilter())
46+
using (var db = OpenDbConnection())
47+
{
48+
int i = 0;
49+
i++; db.CreateTable<Person>();
50+
51+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
52+
Is.StringStarting("create table person"));
53+
54+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
55+
56+
captured.SqlCommandHistory.PrintDump();
57+
58+
}
59+
}
60+
61+
[Test]
62+
public void Can_capture_command_Select_APIs()
63+
{
64+
using (var captured = new CaptureSqlCommandFilter())
65+
using (var db = OpenDbConnection())
66+
{
67+
int i = 0;
68+
i++; db.Select<Person>(x => x.Age > 40);
69+
70+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
71+
Is.EqualTo("select id, firstname, lastname, age from person where (age > 40)"));
72+
73+
i++; db.Select<Person>(q => q.Where(x => x.Age > 40));
74+
i++; db.Select(db.From<Person>().Where(x => x.Age > 40));
75+
i++; db.Select<Person>("Age > 40");
76+
i++; db.Select<Person>("SELECT * FROM Person WHERE Age > 40");
77+
i++; db.Select<Person>("Age > @age", new { age = 40 });
78+
i++; db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new { age = 40 });
79+
i++; db.Select<Person>("Age > @age", new Dictionary<string, object> { { "age", 40 } });
80+
i++; db.SelectFmt<Person>("Age > {0}", 40);
81+
i++; db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40);
82+
i++; db.Where<Person>("Age", 27);
83+
i++; db.Where<Person>(new { Age = 27 });
84+
i++; db.SelectByIds<Person>(new[] { 1, 2, 3 });
85+
i++; db.SelectByIds<Person>(new[] { 1, 2, 3 });
86+
i++; db.SelectNonDefaults(new Person { Id = 1 });
87+
i++; db.SelectNonDefaults("Age > @Age", new Person { Age = 40 });
88+
i++; db.SelectLazy<Person>().ToList();
89+
i++; db.WhereLazy<Person>(new { Age = 27 }).ToList();
90+
i++; db.Select<Person>();
91+
i++; db.Single<Person>(x => x.Age == 42);
92+
i++; db.Single(db.From<Person>().Where(x => x.Age == 42));
93+
i++; db.Single<Person>(new { Age = 42 });
94+
i++; db.Single<Person>("Age = @age", new { age = 42 });
95+
i++; db.SingleById<Person>(1);
96+
i++; db.SingleWhere<Person>("Age", 42);
97+
i++; db.Exists<Person>(new { Age = 42 });
98+
i++; db.Exists<Person>("SELECT * FROM Person WHERE Age = @age", new { age = 42 });
99+
i++; db.ExistsFmt<Person>("Age = {0}", 42);
100+
i++; db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 42);
101+
102+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
103+
104+
captured.SqlCommandHistory.PrintDump();
105+
106+
}
107+
}
108+
109+
[Test]
110+
public void Can_capture_command_all_Single_Apis()
111+
{
112+
using (var captured = new CaptureSqlCommandFilter())
113+
using (var db = OpenDbConnection())
114+
{
115+
int i = 0;
116+
i++; db.Single<Person>(x => x.Age == 42);
117+
118+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
119+
Is.EqualTo("select id, firstname, lastname, age from person where (age = 42) limit 1").
120+
Or.EqualTo("select top 1 id, firstname, lastname, age from person where (age = 42)"));
121+
122+
i++; db.ExistsFmt<Person>("Age = {0}", 42);
123+
i++; db.Single(db.From<Person>().Where(x => x.Age == 42));
124+
i++; db.Single<Person>(new { Age = 42 });
125+
i++; db.Single<Person>("Age = @age", new { age = 42 });
126+
i++; db.SingleFmt<Person>("Age = {0}", 42);
127+
i++; db.SingleById<Person>(1);
128+
i++; db.ExistsFmt<Person>("Age = {0}", 42);
129+
i++; db.SingleWhere<Person>("Age", 42);
130+
131+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
132+
133+
captured.SqlCommandHistory.PrintDump();
134+
135+
}
136+
}
137+
138+
[Test]
139+
public void Can_capture_command_all_Scalar_Apis()
140+
{
141+
using (var captured = new CaptureSqlCommandFilter())
142+
using (var db = OpenDbConnection())
143+
{
144+
int i = 0;
145+
i++; db.Scalar<Person, int>(x => Sql.Max(x.Age));
146+
147+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
148+
Is.EqualTo("select max(age) from person"));
149+
150+
i++; db.Scalar<Person, int>(x => Sql.Max(x.Age));
151+
i++; db.Scalar<Person, int>(x => Sql.Max(x.Age), x => x.Age < 50);
152+
i++; db.Count<Person>(x => x.Age < 50);
153+
i++; db.Count(db.From<Person>().Where(x => x.Age < 50));
154+
i++; db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 });
155+
i++; db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40);
156+
157+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 });
158+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } });
159+
160+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
161+
162+
captured.SqlCommandHistory.PrintDump();
163+
164+
}
165+
}
166+
167+
168+
[Test]
169+
public void Can_capture_command_Update_Apis()
170+
{
171+
using (var captured = new CaptureSqlCommandFilter())
172+
using (var db = OpenDbConnection())
173+
{
174+
int i = 0;
175+
i++; db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 });
176+
177+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
178+
Is.StringStarting("update person set firstname=@firstname, lastname=@lastname"));
179+
180+
i++; db.Update(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } });
181+
i++; db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } });
182+
i++; db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix");
183+
i++; db.Update<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix");
184+
i++; db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix");
185+
i++; db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName);
186+
i++; db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix");
187+
i++; db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName));
188+
i++; db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi"));
189+
i++; db.UpdateFmt<Person>(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix"));
190+
i++; db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix"));
191+
192+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
193+
194+
captured.SqlCommandHistory.PrintDump();
195+
196+
}
197+
}
198+
199+
[Test]
200+
public void Can_capture_command_Delete_Apis()
201+
{
202+
using (var captured = new CaptureSqlCommandFilter())
203+
using (var db = OpenDbConnection())
204+
{
205+
int i = 0;
206+
i++; db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
207+
208+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
209+
Is.EqualTo("delete from person where firstname=@firstname and age=@age"));
210+
211+
i++; db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
212+
i++; db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 });
213+
i++; db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 });
214+
i++; db.DeleteById<Person>(1);
215+
i++; db.DeleteByIds<Person>(new[] { 1, 2, 3 });
216+
i++; db.DeleteFmt<Person>("Age = {0}", 27);
217+
i++; db.DeleteFmt(typeof(Person), "Age = {0}", 27);
218+
i++; db.Delete<Person>(p => p.Age == 27);
219+
i++; db.Delete<Person>(ev => ev.Where(p => p.Age == 27));
220+
i++; db.Delete(db.From<Person>().Where(p => p.Age == 27));
221+
i++; db.DeleteFmt<Person>(where: "Age = {0}".SqlFmt(27));
222+
i++; db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(27));
223+
224+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
225+
226+
captured.SqlCommandHistory.PrintDump();
227+
228+
}
229+
}
230+
231+
[Test]
232+
public void Can_capture_command_CustomSql_Apis()
233+
{
234+
using (var captured = new CaptureSqlCommandFilter())
235+
using (var db = OpenDbConnection())
236+
{
237+
int i = 0;
238+
i++; db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 });
239+
240+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
241+
Is.EqualTo("select lastname from person where age < @age"));
242+
243+
i++; db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 });
244+
i++; db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } });
245+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 });
246+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } });
247+
248+
i++; db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7));
249+
i++; db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 });
250+
251+
i++; db.SqlList<Person>("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 });
252+
i++; db.SqlScalar<Person>("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 });
253+
254+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
255+
256+
captured.SqlCommandHistory.PrintDump();
257+
258+
}
259+
}
260+
261+
[Test]
262+
public void Can_capture_command_Insert_Apis()
263+
{
264+
using (var captured = new CaptureSqlCommandFilter())
265+
using (var db = OpenDbConnection())
266+
{
267+
int i = 0;
268+
i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 });
269+
270+
Assert.That(captured.SqlCommandHistory.Last().Sql.NormalizeSql(),
271+
Is.StringStarting("insert into person (id,firstname,lastname,age) values"));
272+
273+
i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 });
274+
i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } });
275+
i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => ev.Insert(p => new { p.FirstName, p.Age }));
276+
i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => db.From<PersonWithAutoId>().Insert(p => new { p.FirstName, p.Age }));
277+
278+
Assert.That(captured.SqlCommandHistory.Count, Is.EqualTo(i));
279+
280+
captured.SqlCommandHistory.PrintDump();
281+
282+
}
283+
}
284+
285+
}
286+
}

0 commit comments

Comments
 (0)