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

Commit 5e6c096

Browse files
committed
Add CaptureSqlFilter to record SQL Statements without executing them
1 parent 6e4673d commit 5e6c096

File tree

3 files changed

+275
-1
lines changed

3 files changed

+275
-1
lines changed

src/ServiceStack.OrmLite/OrmLiteResultsFilter.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ public object GetScalar(IDbCommand dbCmd)
245245
public List<T> GetColumn<T>(IDbCommand dbCmd)
246246
{
247247
Filter(dbCmd);
248-
return (from object result in GetColumnResults<T>(dbCmd) select (T)result).ToList();
248+
return (from object result in (GetColumnResults<T>(dbCmd) ?? new T[0]) select (T)result).ToList();
249249
}
250250

251251
public HashSet<T> GetColumnDistinct<T>(IDbCommand dbCmd)
@@ -310,4 +310,20 @@ public void Dispose()
310310
OrmLiteConfig.ResultsFilter = previousFilter;
311311
}
312312
}
313+
314+
public class CaptureSqlFilter : OrmLiteResultsFilter
315+
{
316+
public CaptureSqlFilter()
317+
{
318+
SqlFilter = CaptureSql;
319+
SqlStatements = new List<string>();
320+
}
321+
322+
private void CaptureSql(string sql)
323+
{
324+
SqlStatements.Add(sql);
325+
}
326+
327+
public List<string> SqlStatements { get; set; }
328+
}
313329
}
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
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 CaptureSqlFilterTests
11+
: OrmLiteTestBase
12+
{
13+
[Test]
14+
public void Can_capture_CreateTable_APIs()
15+
{
16+
using (var captured = new CaptureSqlFilter())
17+
using (var db = OpenDbConnection())
18+
{
19+
int i = 0;
20+
i++; db.CreateTable<Person>();
21+
22+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
23+
Is.StringStarting("create table person"));
24+
25+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
26+
27+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
28+
sql.Print();
29+
}
30+
}
31+
32+
[Test]
33+
public void Can_capture_Select_APIs()
34+
{
35+
using (var captured = new CaptureSqlFilter())
36+
using (var db = OpenDbConnection())
37+
{
38+
int i = 0;
39+
i++; db.Select<Person>(x => x.Age > 40);
40+
41+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
42+
Is.EqualTo("select id, firstname, lastname, age from person where (age > 40)"));
43+
44+
i++; db.Select<Person>(q => q.Where(x => x.Age > 40));
45+
i++; db.Select(db.From<Person>().Where(x => x.Age > 40));
46+
i++; db.Select<Person>("Age > 40");
47+
i++; db.Select<Person>("SELECT * FROM Person WHERE Age > 40");
48+
i++; db.Select<Person>("Age > @age", new { age = 40 });
49+
i++; db.Select<Person>("SELECT * FROM Person WHERE Age > @age", new { age = 40 });
50+
i++; db.Select<Person>("Age > @age", new Dictionary<string, object> { { "age", 40 } });
51+
i++; db.SelectFmt<Person>("Age > {0}", 40);
52+
i++; db.SelectFmt<Person>("SELECT * FROM Person WHERE Age > {0}", 40);
53+
i++; db.Where<Person>("Age", 27);
54+
i++; db.Where<Person>(new { Age = 27 });
55+
i++; db.SelectByIds<Person>(new[] { 1, 2, 3 });
56+
i++; db.SelectByIds<Person>(new[] { 1, 2, 3 });
57+
i++; db.SelectNonDefaults(new Person { Id = 1 });
58+
i++; db.SelectNonDefaults("Age > @Age", new Person { Age = 40 });
59+
i++; db.SelectLazy<Person>().ToList();
60+
i++; db.WhereLazy<Person>(new { Age = 27 }).ToList();
61+
i++; db.Select<Person>();
62+
i++; db.Single<Person>(x => x.Age == 42);
63+
i++; db.Single(db.From<Person>().Where(x => x.Age == 42));
64+
i++; db.Single<Person>(new { Age = 42 });
65+
i++; db.Single<Person>("Age = @age", new { age = 42 });
66+
i++; db.SingleById<Person>(1);
67+
i++; db.SingleWhere<Person>("Age", 42);
68+
i++; db.Exists<Person>(new { Age = 42 });
69+
i++; db.Exists<Person>("SELECT * FROM Person WHERE Age = @age", new { age = 42 });
70+
i++; db.ExistsFmt<Person>("Age = {0}", 42);
71+
i++; db.ExistsFmt<Person>("SELECT * FROM Person WHERE Age = {0}", 42);
72+
73+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
74+
75+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
76+
sql.Print();
77+
}
78+
}
79+
80+
[Test]
81+
public void Can_capture_all_Single_Apis()
82+
{
83+
using (var captured = new CaptureSqlFilter())
84+
using (var db = OpenDbConnection())
85+
{
86+
int i = 0;
87+
i++; db.Single<Person>(x => x.Age == 42);
88+
89+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
90+
Is.EqualTo("select id, firstname, lastname, age from person where (age = 42) limit 1").
91+
Or.EqualTo("select top 1 id, firstname, lastname, age from person where (age = 42)"));
92+
93+
i++; db.ExistsFmt<Person>("Age = {0}", 42);
94+
i++; db.Single(db.From<Person>().Where(x => x.Age == 42));
95+
i++; db.Single<Person>(new { Age = 42 });
96+
i++; db.Single<Person>("Age = @age", new { age = 42 });
97+
i++; db.SingleFmt<Person>("Age = {0}", 42);
98+
i++; db.SingleById<Person>(1);
99+
i++; db.ExistsFmt<Person>("Age = {0}", 42);
100+
i++; db.SingleWhere<Person>("Age", 42);
101+
102+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
103+
104+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
105+
sql.Print();
106+
}
107+
}
108+
109+
[Test]
110+
public void Can_capture_all_Scalar_Apis()
111+
{
112+
using (var captured = new CaptureSqlFilter())
113+
using (var db = OpenDbConnection())
114+
{
115+
int i = 0;
116+
i++; db.Scalar<Person, int>(x => Sql.Max(x.Age));
117+
118+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
119+
Is.EqualTo("select max(age) from person"));
120+
121+
i++; db.Scalar<Person, int>(x => Sql.Max(x.Age));
122+
i++; db.Scalar<Person, int>(x => Sql.Max(x.Age), x => x.Age < 50);
123+
i++; db.Count<Person>(x => x.Age < 50);
124+
i++; db.Count(db.From<Person>().Where(x => x.Age < 50));
125+
i++; db.Scalar<int>("SELECT COUNT(*) FROM Person WHERE Age > @age", new { age = 40 });
126+
i++; db.ScalarFmt<int>("SELECT COUNT(*) FROM Person WHERE Age > {0}", 40);
127+
128+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 });
129+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } });
130+
131+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
132+
133+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
134+
sql.Print();
135+
}
136+
}
137+
138+
139+
[Test]
140+
public void Can_capture_Update_Apis()
141+
{
142+
using (var captured = new CaptureSqlFilter())
143+
using (var db = OpenDbConnection())
144+
{
145+
int i = 0;
146+
i++; db.Update(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 });
147+
148+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
149+
Is.StringStarting("update person set firstname=@firstname, lastname=@lastname"));
150+
151+
i++; db.Update(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } });
152+
i++; db.UpdateAll(new[] { new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 } });
153+
i++; db.Update(new Person { Id = 1, FirstName = "JJ", Age = 27 }, p => p.LastName == "Hendrix");
154+
i++; db.Update<Person>(new { FirstName = "JJ" }, p => p.LastName == "Hendrix");
155+
i++; db.UpdateNonDefaults(new Person { FirstName = "JJ" }, p => p.LastName == "Hendrix");
156+
i++; db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName);
157+
i++; db.UpdateOnly(new Person { FirstName = "JJ" }, p => p.FirstName, p => p.LastName == "Hendrix");
158+
i++; db.UpdateOnly(new Person { FirstName = "JJ", LastName = "Hendo" }, ev => ev.Update(p => p.FirstName));
159+
i++; db.UpdateOnly(new Person { FirstName = "JJ" }, ev => ev.Update(p => p.FirstName).Where(x => x.FirstName == "Jimi"));
160+
i++; db.UpdateFmt<Person>(set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix"));
161+
i++; db.UpdateFmt(table: "Person", set: "FirstName = {0}".SqlFmt("JJ"), where: "LastName = {0}".SqlFmt("Hendrix"));
162+
163+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
164+
165+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
166+
sql.Print();
167+
}
168+
}
169+
170+
[Test]
171+
public void Can_capture_Delete_Apis()
172+
{
173+
using (var captured = new CaptureSqlFilter())
174+
using (var db = OpenDbConnection())
175+
{
176+
int i = 0;
177+
i++; db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
178+
179+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
180+
Is.EqualTo("delete from person where firstname=@firstname and age=@age"));
181+
182+
i++; db.Delete<Person>(new { FirstName = "Jimi", Age = 27 });
183+
i++; db.Delete(new Person { Id = 1, FirstName = "Jimi", LastName = "Hendrix", Age = 27 });
184+
i++; db.DeleteNonDefaults(new Person { FirstName = "Jimi", Age = 27 });
185+
i++; db.DeleteById<Person>(1);
186+
i++; db.DeleteByIds<Person>(new[] { 1, 2, 3 });
187+
i++; db.DeleteFmt<Person>("Age = {0}", 27);
188+
i++; db.DeleteFmt(typeof(Person), "Age = {0}", 27);
189+
i++; db.Delete<Person>(p => p.Age == 27);
190+
i++; db.Delete<Person>(ev => ev.Where(p => p.Age == 27));
191+
i++; db.Delete(db.From<Person>().Where(p => p.Age == 27));
192+
i++; db.DeleteFmt<Person>(where: "Age = {0}".SqlFmt(27));
193+
i++; db.DeleteFmt(table: "Person", where: "Age = {0}".SqlFmt(27));
194+
195+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
196+
197+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
198+
sql.Print();
199+
}
200+
}
201+
202+
[Test]
203+
public void Can_capture_CustomSql_Apis()
204+
{
205+
using (var captured = new CaptureSqlFilter())
206+
using (var db = OpenDbConnection())
207+
{
208+
int i = 0;
209+
i++; db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 });
210+
211+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
212+
Is.EqualTo("select lastname from person where age < @age"));
213+
214+
i++; db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new { age = 50 });
215+
i++; db.SqlColumn<string>("SELECT LastName FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } });
216+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new { age = 50 });
217+
i++; db.SqlScalar<int>("SELECT COUNT(*) FROM Person WHERE Age < @age", new Dictionary<string, object> { { "age", 50 } });
218+
219+
i++; db.ExecuteNonQuery("UPDATE Person SET LastName={0} WHERE Id={1}".SqlFmt("WaterHouse", 7));
220+
i++; db.ExecuteNonQuery("UPDATE Person SET LastName=@name WHERE Id=@id", new { name = "WaterHouse", id = 7 });
221+
222+
i++; db.SqlList<Person>("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 });
223+
i++; db.SqlScalar<Person>("exec sp_name @firstName, @age", new { firstName = "aName", age = 1 });
224+
225+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
226+
227+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
228+
sql.Print();
229+
}
230+
}
231+
232+
[Test]
233+
public void Can_capture_Insert_Apis()
234+
{
235+
using (var captured = new CaptureSqlFilter())
236+
using (var db = OpenDbConnection())
237+
{
238+
int i = 0;
239+
i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 });
240+
241+
Assert.That(captured.SqlStatements.Last().NormalizeSql(),
242+
Is.StringStarting("insert into person (id,firstname,lastname,age) values"));
243+
244+
i++; db.Insert(new Person { Id = 7, FirstName = "Amy", LastName = "Winehouse", Age = 27 });
245+
i++; db.InsertAll(new[] { new Person { Id = 10, FirstName = "Biggie", LastName = "Smalls", Age = 24 } });
246+
i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => ev.Insert(p => new { p.FirstName, p.Age }));
247+
i++; db.InsertOnly(new PersonWithAutoId { FirstName = "Amy", Age = 27 }, ev => db.SqlExpression<PersonWithAutoId>().Insert(p => new { p.FirstName, p.Age }));
248+
249+
Assert.That(captured.SqlStatements.Count, Is.EqualTo(i));
250+
251+
var sql = string.Join(";\n", captured.SqlStatements.ToArray());
252+
sql.Print();
253+
}
254+
}
255+
256+
}
257+
}

tests/ServiceStack.OrmLite.Tests/ServiceStack.OrmLite.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
<Compile Include="AdoNetDataAccessTests.cs" />
118118
<Compile Include="ApiSqlServerTests.cs" />
119119
<Compile Include="ApiSqliteTests.cs" />
120+
<Compile Include="CaptureSqlFilterTests.cs" />
120121
<Compile Include="CustomSqlTests.cs" />
121122
<Compile Include="DateTimeOffsetTests.cs" />
122123
<Compile Include="Expression\FromExpressionTests.cs" />

0 commit comments

Comments
 (0)