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

Commit 626ec2f

Browse files
committed
Add support for Sql.Custom()
1 parent eb165da commit 626ec2f

File tree

4 files changed

+111
-47
lines changed

4 files changed

+111
-47
lines changed

src/ServiceStack.OrmLite/Expressions/Sql.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static List<object> Flatten(IEnumerable list)
3232

3333
public static bool In<T, TItem>(T value, SqlExpression<TItem> query) => value != null && query != null;
3434

35-
public static string Desc<T>(T value) => value == null ? "" : value.ToString() + " DESC";
35+
public static string Desc<T>(T value) => value == null ? "" : value + " DESC";
3636

3737
public static string As<T>(T value, object asValue) => value == null ? "" : $"{value} AS {asValue}";
3838

@@ -61,6 +61,8 @@ public static List<object> Flatten(IEnumerable list)
6161
public static T AllFields<T>(T item) => item;
6262

6363
public static string JoinAlias<T>(T property, string tableAlias) => tableAlias;
64+
65+
public static string Custom(string customSql) => customSql;
6466
}
6567

6668
}

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,9 @@ protected virtual object VisitSqlMethodCall(MethodCallExpression m)
20612061
case "JoinAlias":
20622062
statement = args[0] + "." + quotedColName.ToString().LastRightPart('.');
20632063
break;
2064+
case "Custom":
2065+
statement = quotedColName.ToString();
2066+
break;
20642067
default:
20652068
throw new NotSupportedException();
20662069
}

tests/ServiceStack.OrmLite.Tests/CustomSqlTests.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NUnit.Framework;
44
using ServiceStack.DataAnnotations;
55
using ServiceStack.OrmLite.Tests.Expression;
6+
using ServiceStack.OrmLite.Tests.Issues;
67
using ServiceStack.Text;
78

89
namespace ServiceStack.OrmLite.Tests
@@ -120,7 +121,7 @@ public void Does_execute_CustomSql_after_table_created()
120121

121122
var seedDataNames = db.Select<ModelWithSeedDataSql>().ConvertAll(x => x.Name);
122123

123-
Assert.That(seedDataNames, Is.EquivalentTo(new[] { "Foo", "Bar" }));
124+
Assert.That(seedDataNames, Is.EquivalentTo(new[] {"Foo", "Bar"}));
124125
}
125126
}
126127

@@ -141,7 +142,7 @@ public void Does_execute_CustomSql_after_table_created_using_dynamic_attribute()
141142

142143
var seedDataNames = db.Select<DynamicAttributeSeedData>().ConvertAll(x => x.Name);
143144

144-
Assert.That(seedDataNames, Is.EquivalentTo(new[] { "Foo", "Bar" }));
145+
Assert.That(seedDataNames, Is.EquivalentTo(new[] {"Foo", "Bar"}));
145146
}
146147
}
147148

@@ -198,7 +199,7 @@ public void Can_select_custom_field_expressions()
198199
{
199200
db.DropAndCreateTable<CustomSelectTest>();
200201

201-
db.Insert(new CustomSelectTest { Id = 1, Width = 10, Height = 5 });
202+
db.Insert(new CustomSelectTest {Id = 1, Width = 10, Height = 5});
202203

203204
var row = db.SingleById<CustomSelectTest>(1);
204205

@@ -213,7 +214,7 @@ public void Can_Count_Distinct()
213214
{
214215
db.DropAndCreateTable<LetterFrequency>();
215216

216-
var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency { Letter = x });
217+
var rows = "A,B,B,C,C,C,D,D,E".Split(',').Map(x => new LetterFrequency {Letter = x});
217218

218219
db.InsertAll(rows);
219220

@@ -230,5 +231,6 @@ public void Can_Count_Distinct()
230231
Assert.That(distinctCount, Is.EqualTo(rows.Map(x => x.Letter).Distinct().Count()));
231232
}
232233
}
234+
233235
}
234236
}

tests/ServiceStack.OrmLite.Tests/Issues/MultipleSelfJoinsWithAliases.cs

Lines changed: 99 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Data;
23
using NUnit.Framework;
34
using ServiceStack.DataAnnotations;
45
using ServiceStack.Text;
@@ -42,51 +43,61 @@ public class SaleView
4243
public Guid TenantId { get; set; }
4344
public string BuyerFirstName { get; set; }
4445
public string BuyerLastName { get; set; }
46+
public string BuyerInitials { get; set; }
4547
public string SellerFirstName { get; set; }
4648
public string SellerLastName { get; set; }
49+
public string SellerInitials { get; set; }
4750
public int AmountCents { get; set; }
4851
}
4952

5053
public class MultipleSelfJoinsWithAliases : OrmLiteTestBase
5154
{
52-
[Test]
53-
public void Can_use_cusom_SqlExpression_to_add_multiple_self_Left_Joins()
55+
private static Sale PopulateData(IDbConnection db, Guid tenantId)
5456
{
55-
using (var db = OpenDbConnection())
56-
{
57-
db.DropTable<Sale>();
58-
db.DropTable<ContactIssue>();
59-
60-
db.CreateTable<ContactIssue>();
61-
db.CreateTable<Sale>();
57+
db.DropTable<Sale>();
58+
db.DropTable<ContactIssue>();
6259

63-
var tenantId = Guid.NewGuid();
60+
db.CreateTable<ContactIssue>();
61+
db.CreateTable<Sale>();
6462

65-
var buyer = new ContactIssue {
66-
Id = Guid.NewGuid(),
67-
TenantId = tenantId,
68-
FirstName = "Buyer",
69-
LastName = "LastBuyer"
70-
};
63+
var buyer = new ContactIssue
64+
{
65+
Id = Guid.NewGuid(),
66+
TenantId = tenantId,
67+
FirstName = "BuyerFirst",
68+
LastName = "LastBuyer"
69+
};
7170

72-
var seller = new ContactIssue {
73-
Id = Guid.NewGuid(),
74-
TenantId = tenantId,
75-
FirstName = "Seller",
76-
LastName = "LastSeller"
77-
};
71+
var seller = new ContactIssue
72+
{
73+
Id = Guid.NewGuid(),
74+
TenantId = tenantId,
75+
FirstName = "SellerFirst",
76+
LastName = "LastSeller"
77+
};
7878

79-
db.Insert(buyer, seller);
79+
db.Insert(buyer, seller);
8080

81-
var sale = new Sale {
82-
Id = Guid.NewGuid(),
83-
TenantId = tenantId,
84-
BuyerId = buyer.Id,
85-
SellerId = seller.Id,
86-
AmountCents = 100,
87-
};
81+
var sale = new Sale
82+
{
83+
Id = Guid.NewGuid(),
84+
TenantId = tenantId,
85+
BuyerId = buyer.Id,
86+
SellerId = seller.Id,
87+
AmountCents = 100,
88+
};
89+
90+
db.Insert(sale);
91+
return sale;
92+
}
8893

89-
db.Insert(sale);
94+
[Test]
95+
public void Can_use_cusom_SqlExpression_to_add_multiple_self_Left_Joins()
96+
{
97+
using (var db = OpenDbConnection())
98+
{
99+
var tenantId = Guid.NewGuid();
100+
var sale = PopulateData(db, tenantId);
90101

91102
var q = db.From<Sale>()
92103
.CustomJoin("LEFT JOIN {0} seller on (Sale.{1} = seller.Id)"
@@ -107,9 +118,10 @@ public void Can_use_cusom_SqlExpression_to_add_multiple_self_Left_Joins()
107118

108119
//Alternative
109120
q = db.From<Sale>()
110-
.LeftJoin<ContactIssue>((s,c) => s.SellerId == c.Id, db.JoinAlias("seller"))
111-
.LeftJoin<ContactIssue>((s,c) => s.BuyerId == c.Id, db.JoinAlias("buyer"))
112-
.Select<Sale, ContactIssue>((s,c) => new {
121+
.LeftJoin<ContactIssue>((s, c) => s.SellerId == c.Id, db.JoinAlias("seller"))
122+
.LeftJoin<ContactIssue>((s, c) => s.BuyerId == c.Id, db.JoinAlias("buyer"))
123+
.Select<Sale, ContactIssue>((s, c) => new
124+
{
113125
s,
114126
BuyerFirstName = Sql.JoinAlias(c.FirstName, "buyer"),
115127
BuyerLastName = Sql.JoinAlias(c.LastName, "buyer"),
@@ -124,26 +136,71 @@ public void Can_use_cusom_SqlExpression_to_add_multiple_self_Left_Joins()
124136

125137

126138
var salesView = sales[0];
127-
139+
128140
//salesView.PrintDump();
129141

130142
Assert.That(salesView.Id, Is.EqualTo(sale.Id));
131143
Assert.That(salesView.TenantId, Is.EqualTo(sale.TenantId));
132-
Assert.That(salesView.BuyerFirstName, Is.EqualTo(buyer.FirstName));
133-
Assert.That(salesView.BuyerLastName, Is.EqualTo(buyer.LastName));
134-
Assert.That(salesView.SellerFirstName, Is.EqualTo(seller.FirstName));
135-
Assert.That(salesView.SellerLastName, Is.EqualTo(seller.LastName));
136144
Assert.That(salesView.AmountCents, Is.EqualTo(sale.AmountCents));
137-
145+
Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst"));
146+
Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer"));
147+
Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst"));
148+
Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller"));
138149

139150
q.Select("seller.*, 0 EOT, buyer.*");
140151

141152
var multi = db.Select<Tuple<ContactIssue, ContactIssue>>(q);
142153
multi.PrintDump();
143154

144-
Assert.That(multi[0].Item1.FirstName, Is.EqualTo("Seller"));
145-
Assert.That(multi[0].Item2.FirstName, Is.EqualTo("Buyer"));
155+
Assert.That(multi[0].Item1.FirstName, Is.EqualTo("SellerFirst"));
156+
Assert.That(multi[0].Item2.FirstName, Is.EqualTo("BuyerFirst"));
157+
}
158+
}
159+
160+
[Test]
161+
public void Can_use_CustomSql()
162+
{
163+
var customFmt = "";
164+
if (Dialect == Dialect.SqlServer || Dialect == Dialect.SqlServer2012)
165+
customFmt = "CONCAT(LEFT({0}, 1),LEFT({1},1))";
166+
else if (Dialect == Dialect.Sqlite)
167+
customFmt = "substr({0}, 1, 1) || substr({1}, 1, 1)";
168+
169+
if (string.IsNullOrEmpty(customFmt))
170+
return;
171+
172+
using (var db = OpenDbConnection())
173+
{
174+
var tenantId = Guid.NewGuid();
175+
var sale = PopulateData(db, tenantId);
176+
177+
var q = db.From<Sale>()
178+
.LeftJoin<ContactIssue>((s, c) => s.SellerId == c.Id, db.JoinAlias("seller"))
179+
.LeftJoin<ContactIssue>((s, c) => s.BuyerId == c.Id, db.JoinAlias("buyer"))
180+
.Select<Sale, ContactIssue>((s, c) => new
181+
{
182+
s,
183+
BuyerFirstName = Sql.JoinAlias(c.FirstName, "buyer"),
184+
BuyerLastName = Sql.JoinAlias(c.LastName, "buyer"),
185+
BuyerInitials = Sql.Custom(customFmt.Fmt("buyer.FirstName", "buyer.LastName")),
186+
SellerFirstName = Sql.JoinAlias(c.FirstName, "seller"),
187+
SellerLastName = Sql.JoinAlias(c.LastName, "seller"),
188+
SellerInitials = Sql.Custom(customFmt.Fmt("seller.FirstName", "seller.LastName")),
189+
});
190+
191+
var sales = db.Select<SaleView>(q);
192+
var salesView = sales[0];
193+
194+
Assert.That(salesView.BuyerFirstName, Is.EqualTo("BuyerFirst"));
195+
Assert.That(salesView.BuyerLastName, Is.EqualTo("LastBuyer"));
196+
Assert.That(salesView.BuyerInitials, Is.EqualTo("BL"));
197+
Assert.That(salesView.SellerFirstName, Is.EqualTo("SellerFirst"));
198+
Assert.That(salesView.SellerLastName, Is.EqualTo("LastSeller"));
199+
Assert.That(salesView.SellerInitials, Is.EqualTo("SL"));
200+
201+
sales.PrintDump();
146202
}
147203
}
204+
148205
}
149206
}

0 commit comments

Comments
 (0)