Skip to content

Commit b799ecb

Browse files
committed
join tests
1 parent a171ffc commit b799ecb

4 files changed

Lines changed: 148 additions & 2 deletions

File tree

SQLitePCL.pretty.Orm/SqlCompiler.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,18 @@ private static string CompileExpr(this Expression This)
116116
else if (This.NodeType == ExpressionType.Convert)
117117
{
118118
var u = (UnaryExpression)This;
119+
120+
// Let SQLite handle the casting for us
121+
var operand = u.Operand;
122+
return operand.CompileExpr();
123+
124+
// FIXME: Might still want to support a direct cast here if the
125+
// operand is a constant value or a function that is evaluated
126+
/*
119127
var ty = u.Type;
120128
var value = EvaluateExpression(u.Operand);
121129
122-
return value.ConvertTo(ty).ConvertToSQLiteValue().ToSqlString();
130+
return value.ConvertTo(ty).ConvertToSQLiteValue().ToSqlString();*/
123131
}
124132
else if (This.NodeType == ExpressionType.Default)
125133
{
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System;
2+
3+
using SQLitePCL.pretty.Orm;
4+
using SQLitePCL.pretty.Orm.Attributes;
5+
6+
using NUnit.Framework;
7+
using RS = SQLitePCL.pretty.Orm.ResultSet;
8+
using System.Linq;
9+
10+
namespace SQLitePCL.pretty.tests
11+
{
12+
public partial class SqlQueryTests
13+
{
14+
public class EmployedBy
15+
{
16+
[PrimaryKey]
17+
public long? Id { get; set; }
18+
19+
[ForeignKey(typeof(Person))]
20+
[Indexed(true)]
21+
public long EmployeeId { get; set; }
22+
23+
[ForeignKey(typeof(Business))]
24+
public long BusinessId { get; set; }
25+
}
26+
27+
public class Business
28+
{
29+
[PrimaryKey]
30+
public long? Id { get; set; }
31+
32+
public string Name { get; set; }
33+
34+
[ForeignKey(typeof(Address))]
35+
public long AddressId { get; set; }
36+
37+
public Uri WebSite { get; set; }
38+
}
39+
40+
public class Person
41+
{
42+
[PrimaryKey]
43+
public long? Id { get; set; }
44+
45+
public string FirstName { get; set; }
46+
47+
public string LastName { get; set; }
48+
49+
[ForeignKey(typeof(Address))]
50+
public long AddressId { get; set; }
51+
52+
public DateTime Birthday { get; set; }
53+
}
54+
55+
public class Address
56+
{
57+
[PrimaryKey]
58+
public long? Id { get; set; }
59+
public uint ZipCode { get; set; }
60+
}
61+
62+
[Test]
63+
public void TestJoins()
64+
{
65+
var addressSelector = RS.RowToObject<Address>();
66+
var personSelector = RS.RowToObject<Person>();
67+
var businessSelector = RS.RowToObject<Business>();
68+
var employedBySelector = RS.RowToObject<EmployedBy>();
69+
70+
using (var db = SQLite3.OpenInMemory())
71+
{
72+
db.InitTable<Address>();
73+
db.InitTable<Person>();
74+
db.InitTable<Business>();
75+
db.InitTable<EmployedBy>();
76+
77+
var addresses =
78+
db.InsertOrReplaceAll(
79+
new Address[]
80+
{
81+
new Address() { ZipCode = 12345 },
82+
new Address() { ZipCode = 67890 }
83+
}, addressSelector).Values.ToList();
84+
85+
var people =
86+
db.InsertOrReplaceAll(
87+
new Person[]
88+
{
89+
new Person() { FirstName = "Bob", LastName = "Doe", AddressId = addresses[0].Id.Value },
90+
new Person() { FirstName = "Jane", LastName = "Doe", AddressId = addresses[0].Id.Value },
91+
new Person() { FirstName = "Doe", LastName = "Adear", AddressId = addresses[1].Id.Value },
92+
new Person() { FirstName = "AFemale", LastName = "Dear", AddressId = addresses[1].Id.Value },
93+
}, personSelector).Values.ToList();
94+
95+
var businesses =
96+
db.InsertOrReplaceAll(
97+
new Business[]
98+
{
99+
new Business() { Name = "ACompany", AddressId = addresses[0].Id.Value, WebSite = new Uri("http://www.acompany.example.com") },
100+
new Business() { Name = "BCompany", AddressId = addresses[1].Id.Value, WebSite = new Uri("http://www.bcompany.example.com") }
101+
}, businessSelector).Values.ToList();
102+
103+
var employeesToBusiness =
104+
db.InsertOrReplaceAll(
105+
new EmployedBy[]
106+
{
107+
new EmployedBy() { EmployeeId = people[0].Id.Value, BusinessId = businesses[0].Id.Value },
108+
new EmployedBy() { EmployeeId = people[1].Id.Value, BusinessId = businesses[0].Id.Value },
109+
new EmployedBy() { EmployeeId = people[2].Id.Value, BusinessId = businesses[1].Id.Value },
110+
new EmployedBy() { EmployeeId = people[2].Id.Value, BusinessId = businesses[0].Id.Value },
111+
}, employedBySelector).Values.ToList();
112+
113+
var peopleWhoWorkAtQuery =
114+
SqlQuery.From<Person>()
115+
.Join<EmployedBy>((person, employedBy) =>
116+
person.Id == employedBy.EmployeeId)
117+
.Join<Business>((person, employedBy, business) =>
118+
business.Id == employedBy.BusinessId)
119+
.SelectDistinct()
120+
.Where<long>((person, employedBy, business, businessId) =>
121+
// FIXME: Would be cool if you could instead use
122+
// business == businesses[0]
123+
// and then introspect the primary keys to make it work
124+
business.Id == businessId);
125+
126+
var peopleWhoWorkAt =
127+
db.Query(peopleWhoWorkAtQuery, businesses[0].Id)
128+
.Select(x =>
129+
Tuple.Create(personSelector(x), businessSelector(x)))
130+
.ToList();
131+
132+
Assert.AreEqual(peopleWhoWorkAt.Count, 3);
133+
}
134+
}
135+
}
136+
}
137+

SQLitePCL.pretty.tests/OrmTests/QueryTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
namespace SQLitePCL.pretty.tests
1111
{
1212
[TestFixture]
13-
public class QueryBuilder_SelectQuery_Tests
13+
public partial class SqlQueryTests
1414
{
1515
public class TestObject
1616
{

SQLitePCL.pretty.tests/SQLitePCL.pretty.tests.x86.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
<Compile Include="OrmTests\TableMappingTests.Sync.cs" />
8787
<Compile Include="OrmTests\TableMappingTest.Async.cs" />
8888
<Compile Include="OrmTests\QueryTests.cs" />
89+
<Compile Include="OrmTests\QueryTests.Joins.cs" />
8990
</ItemGroup>
9091
<ItemGroup>
9192
<ProjectReference Include="..\SQLitePCL.pretty.Async\SQLitePCL.pretty.Async.csproj">

0 commit comments

Comments
 (0)