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

Commit 8e7ed94

Browse files
committed
Switch to use ^ character for escaping LIKE queries as MySql treats \ differently
1 parent e9aaa8e commit 8e7ed94

File tree

6 files changed

+52
-32
lines changed

6 files changed

+52
-32
lines changed

src/ServiceStack.OrmLite.MySql/MySqlExpression.cs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,10 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq.Expressions;
4-
5-
6-
namespace ServiceStack.OrmLite.MySql
1+
namespace ServiceStack.OrmLite.MySql
72
{
83
/// <summary>
94
/// Description of MySqlExpressionVisitor.
105
/// </summary>
116
public class MySqlExpression<T> : SqlExpression<T>
127
{
13-
protected override object VisitColumnAccessMethod(MethodCallExpression m)
14-
{
15-
if (m.Method.Name == "StartsWith")
16-
{
17-
List<Object> args = this.VisitExpressionList(m.Arguments);
18-
var quotedColName = Visit(m.Object);
19-
return new PartialSqlString(string.Format("LEFT( {0},{1})= {2} ", quotedColName
20-
, args[0].ToString().Length,
21-
OrmLiteConfig.DialectProvider.GetQuotedValue(args[0],
22-
args[0].GetType())));
23-
}
24-
25-
return base.VisitColumnAccessMethod(m);
26-
}
27-
288
public override SqlExpression<T> Clone()
299
{
3010
return CopyTo(new MySqlExpression<T>());

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,41 +1307,41 @@ protected virtual object VisitColumnAccessMethod(MethodCallExpression m)
13071307
case "StartsWith":
13081308
if (!OrmLiteConfig.StripUpperInLike)
13091309
{
1310-
statement = string.Format("upper({0}) like {1} escape '\\'",
1310+
statement = string.Format("upper({0}) like {1} escape '^'",
13111311
quotedColName, OrmLiteConfig.DialectProvider.GetQuotedValue(
13121312
OrmLiteConfig.DialectProvider.EscapeWildcards(args[0].ToString()).ToUpper() + "%"));
13131313
}
13141314
else
13151315
{
1316-
statement = string.Format("{0} like {1} escape '\\'",
1316+
statement = string.Format("{0} like {1} escape '^'",
13171317
quotedColName, OrmLiteConfig.DialectProvider.GetQuotedValue(
13181318
OrmLiteConfig.DialectProvider.EscapeWildcards(args[0].ToString()) + "%"));
13191319
}
13201320
break;
13211321
case "EndsWith":
13221322
if (!OrmLiteConfig.StripUpperInLike)
13231323
{
1324-
statement = string.Format("upper({0}) like {1} escape '\\'",
1324+
statement = string.Format("upper({0}) like {1} escape '^'",
13251325
quotedColName, OrmLiteConfig.DialectProvider.GetQuotedValue("%" +
13261326
OrmLiteConfig.DialectProvider.EscapeWildcards(args[0].ToString()).ToUpper()));
13271327
}
13281328
else
13291329
{
1330-
statement = string.Format("{0} like {1} escape '\\'",
1330+
statement = string.Format("{0} like {1} escape '^'",
13311331
quotedColName, OrmLiteConfig.DialectProvider.GetQuotedValue("%" +
13321332
OrmLiteConfig.DialectProvider.EscapeWildcards(args[0].ToString())));
13331333
}
13341334
break;
13351335
case "Contains":
13361336
if (!OrmLiteConfig.StripUpperInLike)
13371337
{
1338-
statement = string.Format("upper({0}) like {1} escape '\\'",
1338+
statement = string.Format("upper({0}) like {1} escape '^'",
13391339
quotedColName, OrmLiteConfig.DialectProvider.GetQuotedValue("%" +
13401340
OrmLiteConfig.DialectProvider.EscapeWildcards(args[0].ToString()).ToUpper() + "%"));
13411341
}
13421342
else
13431343
{
1344-
statement = string.Format("{0} like {1} escape '\\'",
1344+
statement = string.Format("{0} like {1} escape '^'",
13451345
quotedColName, OrmLiteConfig.DialectProvider.GetQuotedValue("%" +
13461346
OrmLiteConfig.DialectProvider.EscapeWildcards(args[0].ToString()) + "%"));
13471347
}

src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,9 +1295,10 @@ public virtual string EscapeWildcards(string value)
12951295
return null;
12961296

12971297
return value
1298-
.Replace(@"\", @"\\")
1299-
.Replace("_", @"\_")
1300-
.Replace("%", @"\%");
1298+
.Replace("^", @"^^")
1299+
.Replace(@"\", @"^\")
1300+
.Replace("_", @"^_")
1301+
.Replace("%", @"^%");
13011302
}
13021303
}
13031304
}

tests/ServiceStack.OrmLite.Tests/CaptureSqlFilterTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public void Can_capture_each_type_of_API()
3838
[Test]
3939
public void Can_capture_CreateTable_APIs()
4040
{
41+
using (var db = OpenDbConnection())
42+
{
43+
db.DropTable<Person>();
44+
}
45+
4146
using (var captured = new CaptureSqlFilter())
4247
using (var db = OpenDbConnection())
4348
{

tests/ServiceStack.OrmLite.Tests/Expression/SelectExpressionTests.cs

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

89
namespace ServiceStack.OrmLite.Tests.Expression
@@ -158,13 +159,45 @@ public void Can_escape_wildcards()
158159
db.Insert(new Poco { Name = "a\\" });
159160
db.Insert(new Poco { Name = "a\\b" });
160161
db.Insert(new Poco { Name = "a\\bc" });
162+
db.Insert(new Poco { Name = "a^" });
163+
db.Insert(new Poco { Name = "a^b" });
164+
db.Insert(new Poco { Name = "a^bc" });
161165

162166
Assert.That(db.Count<Poco>(q => q.Name == "a_"), Is.EqualTo(0));
163167
Assert.That(db.Count<Poco>(q => q.Name.StartsWith("a_")), Is.EqualTo(2));
164168
Assert.That(db.Count<Poco>(q => q.Name.StartsWith("a%")), Is.EqualTo(3));
165169
Assert.That(db.Count<Poco>(q => q.Name.StartsWith("a_c")), Is.EqualTo(2));
166170
Assert.That(db.Count<Poco>(q => q.Name.StartsWith(@"a\")), Is.EqualTo(3));
167171
Assert.That(db.Count<Poco>(q => q.Name.StartsWith(@"a\b")), Is.EqualTo(2));
172+
Assert.That(db.Count<Poco>(q => q.Name.StartsWith(@"a^")), Is.EqualTo(3));
173+
Assert.That(db.Count<Poco>(q => q.Name.StartsWith(@"a^b")), Is.EqualTo(2));
174+
Assert.That(db.Count<Poco>(q => q.Name.EndsWith(@"_cd")), Is.EqualTo(1));
175+
Assert.That(db.Count<Poco>(q => q.Name.Contains(@"abc")), Is.EqualTo(1));
176+
}
177+
}
178+
179+
[Test]
180+
public void Can_have_multiple_escape_wildcards()
181+
{
182+
using (var db = OpenDbConnection())
183+
{
184+
db.DropAndCreateTable<Person>();
185+
186+
db.Save(new Person
187+
{
188+
FirstName = "First",
189+
LastName = "Last",
190+
});
191+
192+
var someText = "ast";
193+
194+
var ev = db.From<Person>();
195+
ev.Where(p => p.FirstName.Contains(someText)
196+
|| p.LastName.Contains(someText));
197+
ev.OrderBy(p => p.LastName).ThenBy(p => p.FirstName);
198+
var rows = db.Select(ev);
199+
200+
Assert.That(rows.Count, Is.EqualTo(1));
168201
}
169202
}
170203

tests/ServiceStack.OrmLite.Tests/TestHelpers.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ public static string NormalizeSql(this string sql)
1717
return sql.ToLower()
1818
.Replace("\"", "")
1919
.Replace("`", "")
20-
.Replace("_","")
21-
.Replace("\n", " ");
20+
.Replace("_", "")
21+
.Replace(":", "@") //postgresql
22+
.Replace("\n", " ");
2223
}
2324
}
2425
}

0 commit comments

Comments
 (0)