Skip to content
This repository has been archived by the owner on Feb 29, 2020. It is now read-only.

Commit

Permalink
[client][managed][offline] fixed the like implementation in sqlite store
Browse files Browse the repository at this point in the history
  • Loading branch information
hasankhan committed Oct 9, 2014
1 parent 7a40c9f commit 77a0180
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MobileServices.Query;
using Newtonsoft.Json.Linq;

namespace Microsoft.WindowsAzure.MobileServices.SQLiteStore
{
internal class SqlQueryFormatter: QueryNodeVisitor<QueryNode>
internal class SqlQueryFormatter : QueryNodeVisitor<QueryNode>
{
private MobileServiceTableQueryDescription query;
private StringBuilder sql;

public IDictionary<string, object> Parameters { get; private set; }

public SqlQueryFormatter(MobileServiceTableQueryDescription query)
Expand Down Expand Up @@ -47,7 +46,7 @@ public string FormatSelectCount()

if (this.query.IncludeTotalCount)
{
this.FormatCountQuery();
this.FormatCountQuery();
}

return GetSql();
Expand All @@ -60,7 +59,7 @@ public string FormatDelete()
delQuery.Selection.Clear();
delQuery.Selection.Add(MobileServiceSystemColumns.Id);
delQuery.IncludeTotalCount = false;

var formatter = new SqlQueryFormatter(delQuery);
string selectIdQuery = formatter.FormatSelect();
string idMemberName = SqlHelpers.FormatMember(MobileServiceSystemColumns.Id);
Expand All @@ -74,7 +73,7 @@ public string FormatDelete()
private string FormatQuery(string command)
{
Reset();

this.sql.Append(command);

string tableName = SqlHelpers.FormatTableName(this.query.TableName);
Expand Down Expand Up @@ -158,9 +157,9 @@ public override QueryNode Visit(BinaryOperatorNode nodeIn)
this.sql.Append("(");

QueryNode left = nodeIn.LeftOperand;
QueryNode right = nodeIn.RightOperand;
if (left != null)
QueryNode right = nodeIn.RightOperand;

if (left != null)
{
// modulo requires the dividend to be an integer, monetary or numeric
// rewrite the expression to convert to numeric, allowing the DB to apply
Expand All @@ -175,22 +174,22 @@ public override QueryNode Visit(BinaryOperatorNode nodeIn)
}

var rightConstant = right as ConstantNode;
if (rightConstant != null && rightConstant.Value == null)
if (rightConstant != null && rightConstant.Value == null)
{
// inequality expressions against a null literal have a special
// translation in SQL
if (nodeIn.OperatorKind == BinaryOperatorKind.Equal)
if (nodeIn.OperatorKind == BinaryOperatorKind.Equal)
{
this.sql.Append(" IS NULL");
}
else if (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual)
else if (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual)
{
this.sql.Append(" IS NOT NULL");
}
}
else
else
{
switch (nodeIn.OperatorKind)
switch (nodeIn.OperatorKind)
{
case BinaryOperatorKind.Equal:
this.sql.Append(" = ");
Expand Down Expand Up @@ -232,7 +231,7 @@ public override QueryNode Visit(BinaryOperatorNode nodeIn)
this.sql.Append(" % ");
break;
}

if (right != null)
{
right = right.Accept(this);
Expand All @@ -259,10 +258,10 @@ public override QueryNode Visit(ConstantNode nodeIn)
{
this.sql.Append(this.CreateParameter(nodeIn.Value));
}


return nodeIn;
}
}

public override QueryNode Visit(MemberAccessNode nodeIn)
{
Expand Down Expand Up @@ -303,11 +302,11 @@ public override QueryNode Visit(FunctionCallNode nodeIn)
case "trim":
return this.FormatStringFunction("TRIM", nodeIn);
case "substringof":
return this.FormatLikeFunction(true, nodeIn, true);
return this.FormatLikeFunction(true, nodeIn, 0, 1, true);
case "startswith":
return this.FormatLikeFunction(false, nodeIn, true);
return this.FormatLikeFunction(false, nodeIn, 1, 0, true);
case "endswith":
return this.FormatLikeFunction(true, nodeIn, false);
return this.FormatLikeFunction(true, nodeIn, 1, 0, false);
case "concat":
return this.FormatConcatFunction(nodeIn);
case "indexof":
Expand All @@ -321,21 +320,21 @@ public override QueryNode Visit(FunctionCallNode nodeIn)
throw new NotImplementedException();
}

private QueryNode FormatLikeFunction(bool startAny, FunctionCallNode nodeIn, bool endAny)
private QueryNode FormatLikeFunction(bool startAny, FunctionCallNode nodeIn, int patternIndex, int valueIndex, bool endAny)
{
// like('%pattern%', column)
// like('%pattern%', value)
this.sql.Append("LIKE(");
if (startAny)
{
this.sql.Append("'%' || ");
}
nodeIn.Arguments[1].Accept(this);
nodeIn.Arguments[patternIndex].Accept(this);
if (endAny)
{
this.sql.Append(" || '%'");
}
this.sql.Append(", ");
nodeIn.Arguments[0].Accept(this);
nodeIn.Arguments[valueIndex].Accept(this);
this.sql.Append(")");

return nodeIn;
Expand Down Expand Up @@ -391,7 +390,7 @@ private QueryNode FormatStringFunction(string fn, FunctionCallNode nodeIn)
separator = ", ";
}
this.sql.Append(")");

return nodeIn;
}

Expand Down Expand Up @@ -474,15 +473,15 @@ public override QueryNode Visit(UnaryOperatorNode nodeIn)
return new UnaryOperatorNode(nodeIn.OperatorKind, operand);
}

return nodeIn;
return nodeIn;
}

public override QueryNode Visit(ConvertNode nodeIn)
{
this.sql.Append("CAST(");

QueryNode source = nodeIn.Source.Accept(this);

this.sql.Append(" AS ");

string sqlType = SqlHelpers.GetColumnType(nodeIn.TargetType);
Expand All @@ -504,6 +503,6 @@ private string CreateParameter(object value)
string paramName = "@p" + paramNumber;
this.Parameters.Add(paramName, SqlHelpers.SerializeValue(new JValue(value), allowNull: true));
return paramName;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public void FormatSelect_String_Trim()
[TestMethod]
public void FormatSelect_String_SubstringOf()
{
TestSelectStringFunction("substringof(name, 'khan')", "LIKE('%' || @p1 || '%', [name])", "khan");
TestSelectStringFunction("substringof('khan', name)", "LIKE('%' || @p1 || '%', [name])", "khan");
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@
// ----------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.MobileServices.Query;
using Microsoft.WindowsAzure.MobileServices.SQLiteStore;
using Microsoft.WindowsAzure.MobileServices.TestFramework;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using SQLitePCL;

namespace Microsoft.WindowsAzure.MobileServices.SQLiteStore.Test.UnitTests
{
Expand Down Expand Up @@ -145,8 +140,22 @@ public async Task Query_OnString_IndexOf()
[AsyncTestMethod]
public async Task Query_OnString_SubstringOf()
{
await TestQuery("$filter=substringof(col1, 'ump')", 1);
await TestQuery("$filter=substringof(col1, 'umx')", 0);
await TestQuery("$filter=substringof('ump', col1)", 1);
await TestQuery("$filter=substringof('umx', col1)", 0);
}

[AsyncTestMethod]
public async Task Query_OnString_StartsWith()
{
await TestQuery("$filter=startswith(col1, 'jum')", 1);
await TestQuery("$filter=startswith(col1, 'pum')", 0);
}

[AsyncTestMethod]
public async Task Query_OnString_EndsWith()
{
await TestQuery("$filter=endswith(col1, 'umped')", 1);
await TestQuery("$filter=endswith(col1, 'umxed')", 0);
}

[AsyncTestMethod]
Expand Down

0 comments on commit 77a0180

Please sign in to comment.