Skip to content

Commit 1b809da

Browse files
authored
Merge pull request #577 from andrew-tavera/master
Case sensitivity in System.String methods used in LINQ queries
2 parents ff09316 + feca677 commit 1b809da

File tree

2 files changed

+68
-16
lines changed

2 files changed

+68
-16
lines changed

src/SQLite.cs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,17 +2997,49 @@ private CompileResult CompileExpr (Expression expr, List<object> queryArgs)
29972997
}
29982998
else if (call.Method.Name == "Contains" && args.Length == 1) {
29992999
if (call.Object != null && call.Object.Type == typeof(string)) {
3000-
sqlCall = "(" + obj.CommandText + " like ('%' || " + args [0].CommandText + " || '%'))";
3000+
sqlCall = "( instr(" + obj.CommandText + "," + args [0].CommandText + ") >0 )";
30013001
}
30023002
else {
30033003
sqlCall = "(" + args [0].CommandText + " in " + obj.CommandText + ")";
30043004
}
30053005
}
3006-
else if (call.Method.Name == "StartsWith" && args.Length == 1) {
3007-
sqlCall = "(" + obj.CommandText + " like (" + args [0].CommandText + " || '%'))";
3008-
}
3009-
else if (call.Method.Name == "EndsWith" && args.Length == 1) {
3010-
sqlCall = "(" + obj.CommandText + " like ('%' || " + args [0].CommandText + "))";
3006+
else if (call.Method.Name == "StartsWith" && args.Length >= 1)
3007+
{
3008+
var startsWithCmpOp = StringComparison.CurrentCulture;
3009+
if (args.Length == 2)
3010+
{
3011+
startsWithCmpOp = (StringComparison) args[1].Value;
3012+
}
3013+
switch (startsWithCmpOp)
3014+
{
3015+
case StringComparison.Ordinal:
3016+
case StringComparison.CurrentCulture:
3017+
sqlCall = "( substr(" + obj.CommandText + ", 1, " + args[0].Value.ToString().Length + ") = " + args[0].CommandText + ")";
3018+
break;
3019+
case StringComparison.OrdinalIgnoreCase:
3020+
case StringComparison.CurrentCultureIgnoreCase:
3021+
sqlCall = "(" + obj.CommandText + " like (" + args[0].CommandText + " || '%'))";
3022+
break;
3023+
}
3024+
3025+
}
3026+
else if (call.Method.Name == "EndsWith" && args.Length >= 1) {
3027+
var endsWithCmpOp = StringComparison.CurrentCulture;
3028+
if (args.Length == 2)
3029+
{
3030+
endsWithCmpOp = (StringComparison)args[1].Value;
3031+
}
3032+
switch (endsWithCmpOp)
3033+
{
3034+
case StringComparison.Ordinal:
3035+
case StringComparison.CurrentCulture:
3036+
sqlCall = "( substr(" + obj.CommandText + ", length(" + obj.CommandText + ") - "+args[0].Value.ToString().Length+ "+1, " + args[0].Value.ToString().Length + ") = " + args[0].CommandText + ")";
3037+
break;
3038+
case StringComparison.OrdinalIgnoreCase:
3039+
case StringComparison.CurrentCultureIgnoreCase:
3040+
sqlCall = "(" + obj.CommandText + " like ('%' || " + args[0].CommandText + "))";
3041+
break;
3042+
}
30113043
}
30123044
else if (call.Method.Name == "Equals" && args.Length == 1) {
30133045
sqlCall = "(" + obj.CommandText + " = (" + args[0].CommandText + "))";

tests/StringQueryTest.cs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,29 +62,49 @@ public void StartsWith ()
6262
{
6363
var fs = db.Table<Product> ().Where (x => x.Name.StartsWith ("F")).ToList ();
6464
Assert.AreEqual (2, fs.Count);
65-
66-
var bs = db.Table<Product> ().Where (x => x.Name.StartsWith ("B")).ToList ();
65+
66+
var lfs = db.Table<Product>().Where(x => x.Name.StartsWith("f")).ToList();
67+
Assert.AreEqual(0, lfs.Count);
68+
69+
70+
var lfs2 = db.Table<Product>().Where(x => x.Name.StartsWith("f",StringComparison.OrdinalIgnoreCase)).ToList();
71+
Assert.AreEqual(2, lfs2.Count);
72+
73+
74+
var bs = db.Table<Product> ().Where (x => x.Name.StartsWith ("B")).ToList ();
6775
Assert.AreEqual (1, bs.Count);
6876
}
6977

7078
[Test]
7179
public void EndsWith ()
7280
{
7381
var fs = db.Table<Product> ().Where (x => x.Name.EndsWith ("ar")).ToList ();
74-
Assert.AreEqual (2, fs.Count);
75-
76-
var bs = db.Table<Product> ().Where (x => x.Name.EndsWith ("o")).ToList ();
82+
Assert.AreEqual (2, fs.Count);
83+
84+
var lfs = db.Table<Product>().Where(x => x.Name.EndsWith("Ar")).ToList();
85+
Assert.AreEqual(0, lfs.Count);
86+
87+
var bs = db.Table<Product> ().Where (x => x.Name.EndsWith ("o")).ToList ();
7788
Assert.AreEqual (1, bs.Count);
7889
}
7990

8091
[Test]
8192
public void Contains ()
8293
{
83-
var fs = db.Table<Product> ().Where (x => x.Name.Contains ("o")).ToList ();
84-
Assert.AreEqual (2, fs.Count);
85-
86-
var bs = db.Table<Product> ().Where (x => x.Name.Contains ("a")).ToList ();
94+
var fs = db.Table<Product>().Where(x => x.Name.Contains("o")).ToList();
95+
Assert.AreEqual(2, fs.Count);
96+
97+
var lfs = db.Table<Product> ().Where (x => x.Name.Contains ("O")).ToList ();
98+
Assert.AreEqual (0, lfs.Count);
99+
100+
var lfsu = db.Table<Product>().Where(x => x.Name.ToUpper().Contains("O")).ToList();
101+
Assert.AreEqual(2, lfsu.Count);
102+
103+
var bs = db.Table<Product> ().Where (x => x.Name.Contains ("a")).ToList ();
87104
Assert.AreEqual (2, bs.Count);
88-
}
105+
106+
var zs = db.Table<Product>().Where(x => x.Name.Contains("z")).ToList();
107+
Assert.AreEqual(0, zs.Count);
108+
}
89109
}
90110
}

0 commit comments

Comments
 (0)