Skip to content

Commit

Permalink
Merge pull request #577 from andrew-tavera/master
Browse files Browse the repository at this point in the history
Case sensitivity in System.String methods used in LINQ queries
  • Loading branch information
praeclarum authored Jul 27, 2017
2 parents ff09316 + feca677 commit 1b809da
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 16 deletions.
44 changes: 38 additions & 6 deletions src/SQLite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2997,17 +2997,49 @@ private CompileResult CompileExpr (Expression expr, List<object> queryArgs)
}
else if (call.Method.Name == "Contains" && args.Length == 1) {
if (call.Object != null && call.Object.Type == typeof(string)) {
sqlCall = "(" + obj.CommandText + " like ('%' || " + args [0].CommandText + " || '%'))";
sqlCall = "( instr(" + obj.CommandText + "," + args [0].CommandText + ") >0 )";
}
else {
sqlCall = "(" + args [0].CommandText + " in " + obj.CommandText + ")";
}
}
else if (call.Method.Name == "StartsWith" && args.Length == 1) {
sqlCall = "(" + obj.CommandText + " like (" + args [0].CommandText + " || '%'))";
}
else if (call.Method.Name == "EndsWith" && args.Length == 1) {
sqlCall = "(" + obj.CommandText + " like ('%' || " + args [0].CommandText + "))";
else if (call.Method.Name == "StartsWith" && args.Length >= 1)
{
var startsWithCmpOp = StringComparison.CurrentCulture;
if (args.Length == 2)
{
startsWithCmpOp = (StringComparison) args[1].Value;
}
switch (startsWithCmpOp)
{
case StringComparison.Ordinal:
case StringComparison.CurrentCulture:
sqlCall = "( substr(" + obj.CommandText + ", 1, " + args[0].Value.ToString().Length + ") = " + args[0].CommandText + ")";
break;
case StringComparison.OrdinalIgnoreCase:
case StringComparison.CurrentCultureIgnoreCase:
sqlCall = "(" + obj.CommandText + " like (" + args[0].CommandText + " || '%'))";
break;
}

}
else if (call.Method.Name == "EndsWith" && args.Length >= 1) {
var endsWithCmpOp = StringComparison.CurrentCulture;
if (args.Length == 2)
{
endsWithCmpOp = (StringComparison)args[1].Value;
}
switch (endsWithCmpOp)
{
case StringComparison.Ordinal:
case StringComparison.CurrentCulture:
sqlCall = "( substr(" + obj.CommandText + ", length(" + obj.CommandText + ") - "+args[0].Value.ToString().Length+ "+1, " + args[0].Value.ToString().Length + ") = " + args[0].CommandText + ")";
break;
case StringComparison.OrdinalIgnoreCase:
case StringComparison.CurrentCultureIgnoreCase:
sqlCall = "(" + obj.CommandText + " like ('%' || " + args[0].CommandText + "))";
break;
}
}
else if (call.Method.Name == "Equals" && args.Length == 1) {
sqlCall = "(" + obj.CommandText + " = (" + args[0].CommandText + "))";
Expand Down
40 changes: 30 additions & 10 deletions tests/StringQueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,49 @@ public void StartsWith ()
{
var fs = db.Table<Product> ().Where (x => x.Name.StartsWith ("F")).ToList ();
Assert.AreEqual (2, fs.Count);

var bs = db.Table<Product> ().Where (x => x.Name.StartsWith ("B")).ToList ();

var lfs = db.Table<Product>().Where(x => x.Name.StartsWith("f")).ToList();
Assert.AreEqual(0, lfs.Count);


var lfs2 = db.Table<Product>().Where(x => x.Name.StartsWith("f",StringComparison.OrdinalIgnoreCase)).ToList();
Assert.AreEqual(2, lfs2.Count);


var bs = db.Table<Product> ().Where (x => x.Name.StartsWith ("B")).ToList ();
Assert.AreEqual (1, bs.Count);
}

[Test]
public void EndsWith ()
{
var fs = db.Table<Product> ().Where (x => x.Name.EndsWith ("ar")).ToList ();
Assert.AreEqual (2, fs.Count);

var bs = db.Table<Product> ().Where (x => x.Name.EndsWith ("o")).ToList ();
Assert.AreEqual (2, fs.Count);

var lfs = db.Table<Product>().Where(x => x.Name.EndsWith("Ar")).ToList();
Assert.AreEqual(0, lfs.Count);

var bs = db.Table<Product> ().Where (x => x.Name.EndsWith ("o")).ToList ();
Assert.AreEqual (1, bs.Count);
}

[Test]
public void Contains ()
{
var fs = db.Table<Product> ().Where (x => x.Name.Contains ("o")).ToList ();
Assert.AreEqual (2, fs.Count);

var bs = db.Table<Product> ().Where (x => x.Name.Contains ("a")).ToList ();
var fs = db.Table<Product>().Where(x => x.Name.Contains("o")).ToList();
Assert.AreEqual(2, fs.Count);

var lfs = db.Table<Product> ().Where (x => x.Name.Contains ("O")).ToList ();
Assert.AreEqual (0, lfs.Count);

var lfsu = db.Table<Product>().Where(x => x.Name.ToUpper().Contains("O")).ToList();
Assert.AreEqual(2, lfsu.Count);

var bs = db.Table<Product> ().Where (x => x.Name.Contains ("a")).ToList ();
Assert.AreEqual (2, bs.Count);
}

var zs = db.Table<Product>().Where(x => x.Name.Contains("z")).ToList();
Assert.AreEqual(0, zs.Count);
}
}
}

0 comments on commit 1b809da

Please sign in to comment.