Skip to content

Commit 7e7432e

Browse files
committed
Added Query paging support to SqlCe40 provider
1 parent e6ea15d commit 7e7432e

7 files changed

Lines changed: 138 additions & 0 deletions

File tree

Simple.Data.SqlCe40/Simple.Data.SqlCe40.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
<DependentUpon>Resources.resx</DependentUpon>
5656
</Compile>
5757
<Compile Include="SqlCe40ConnectionProvider.cs" />
58+
<Compile Include="SqlCe40QueryPager.cs" />
5859
<Compile Include="SqlCe40SchemaProvider.cs" />
5960
<Compile Include="SqlTypeResolver.cs" />
6061
</ItemGroup>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.Composition;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Text.RegularExpressions;
7+
using Simple.Data.Ado;
8+
9+
namespace Simple.Data.SqlCe40
10+
{
11+
[Export(typeof(IQueryPager))]
12+
public class SqlCe40QueryPager : IQueryPager
13+
{
14+
private static readonly Regex ColumnExtract = new Regex(@"SELECT\s*(.*)\s*(FROM.*)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
15+
16+
public string ApplyPaging(string sql, string skipParameterName, string takeParameterName)
17+
{
18+
if (sql.IndexOf("order by", StringComparison.InvariantCultureIgnoreCase) < 0)
19+
{
20+
var match = ColumnExtract.Match(sql);
21+
var columns = match.Groups[1].Value.Trim();
22+
sql += " ORDER BY " + columns.Split(',').First().Trim();
23+
}
24+
25+
return string.Format("{0} OFFSET {1} ROWS FETCH NEXT {2} ROWS ONLY", sql, skipParameterName, takeParameterName);
26+
}
27+
28+
private static string ExtractOrderBy(string columns, ref string fromEtc)
29+
{
30+
string orderBy;
31+
int index = fromEtc.IndexOf("ORDER BY", StringComparison.InvariantCultureIgnoreCase);
32+
if (index > -1)
33+
{
34+
orderBy = fromEtc.Substring(index).Trim();
35+
fromEtc = fromEtc.Remove(index).Trim();
36+
}
37+
else
38+
{
39+
orderBy = "ORDER BY " + columns.Split(',').First().Trim();
40+
}
41+
return orderBy;
42+
}
43+
}
44+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.IO;
2+
using System.Reflection;
3+
using NUnit.Framework;
4+
5+
namespace Simple.Data.SqlCe40Test
6+
{
7+
[TestFixture]
8+
public class QueryTest
9+
{
10+
private static readonly string DatabasePath = Path.Combine(
11+
Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Substring(8)),
12+
"TestDatabase.sdf");
13+
14+
[Test]
15+
public void ShouldSelectFromOneToTen()
16+
{
17+
var db = Database.Opener.OpenFile(DatabasePath);
18+
var query = db.PagingTest.QueryById(1.to(100)).Take(10);
19+
int index = 1;
20+
foreach (var row in query)
21+
{
22+
Assert.AreEqual(index, row.Id);
23+
index++;
24+
}
25+
}
26+
27+
[Test]
28+
public void ShouldSelectFromElevenToTwenty()
29+
{
30+
var db = Database.Opener.OpenFile(DatabasePath);
31+
var query = db.PagingTest.QueryById(1.to(100)).Skip(10).Take(10);
32+
int index = 11;
33+
foreach (var row in query)
34+
{
35+
Assert.AreEqual(index, row.Id);
36+
index++;
37+
}
38+
}
39+
40+
[Test]
41+
public void ShouldSelectFromOneHundredToNinetyOne()
42+
{
43+
var db = Database.Opener.OpenFile(DatabasePath);
44+
var query = db.PagingTest.QueryById(1.to(100)).OrderByDescending(db.PagingTest.Id).Skip(0).Take(10);
45+
int index = 100;
46+
foreach (var row in query)
47+
{
48+
Assert.AreEqual(index, row.Id);
49+
index--;
50+
}
51+
}
52+
}
53+
}

Simple.Data.SqlCe40Test/Simple.Data.SqlCe40Test.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
<Compile Include="NorthwindTests.cs" />
7878
<Compile Include="OrderDetailTests.cs" />
7979
<Compile Include="Properties\AssemblyInfo.cs" />
80+
<Compile Include="QueryTest.cs" />
81+
<Compile Include="SqlCe40QueryPagerTest.cs" />
8082
<Compile Include="SchemaTests\DatabaseSchemaTests.cs" />
8183
<Compile Include="User.cs" />
8284
</ItemGroup>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System.Text.RegularExpressions;
2+
using NUnit.Framework;
3+
using Simple.Data.SqlCe40;
4+
5+
namespace Simple.Data.SqlCe40Test
6+
{
7+
[TestFixture]
8+
public class SqlCe40QueryPagerTest
9+
{
10+
static readonly Regex Normalize = new Regex(@"\s+", RegexOptions.Multiline);
11+
12+
[Test]
13+
public void ShouldApplyPagingUsingOrderBy()
14+
{
15+
const string sql = "select a,b,c from d where a = 1 order by c";
16+
const string expected =
17+
"select a,b,c from d where a = 1 order by c offset @skip rows fetch next @take rows only";
18+
19+
var modified = new SqlCe40QueryPager().ApplyPaging(sql, "@skip", "@take");
20+
modified = Normalize.Replace(modified, " ").ToLowerInvariant();
21+
22+
Assert.AreEqual(expected, modified);
23+
}
24+
25+
[Test]
26+
public void ShouldApplyPagingUsingOrderByFirstColumnIfNotAlreadyOrdered()
27+
{
28+
const string sql = "select a,b,c from d where a = 1";
29+
const string expected =
30+
"select a,b,c from d where a = 1 order by a offset @skip rows fetch next @take rows only";
31+
32+
var modified = new SqlCe40QueryPager().ApplyPaging(sql, "@skip", "@take");
33+
modified = Normalize.Replace(modified, " ").ToLowerInvariant();
34+
35+
Assert.AreEqual(expected, modified);
36+
}
37+
}
38+
}
-20 KB
Binary file not shown.
148 KB
Binary file not shown.

0 commit comments

Comments
 (0)