Skip to content

Commit

Permalink
Added more support for Mysql's JSON type throught phrases
Browse files Browse the repository at this point in the history
  • Loading branch information
danielgindi committed Jun 25, 2018
1 parent 7fa64bf commit ea6af58
Show file tree
Hide file tree
Showing 11 changed files with 1,182 additions and 105 deletions.
189 changes: 189 additions & 0 deletions dg.Sql/Sql/Base Types/JsonPathValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
using System;
using System.Collections.Generic;
using System.Text;
using dg.Sql.Connector;

namespace dg.Sql
{
public class JsonPathValue
{
public string Path;
public ValueWrapper Value;

#region Constructors

public JsonPathValue()
{
this.Value = new ValueWrapper();
}

public JsonPathValue(string path, string tableName, string columnName)
{
this.Path = path;
this.Value = new ValueWrapper(tableName, columnName);
}

public JsonPathValue(string path, string column)
{
this.Path = path;
this.Value = new ValueWrapper(column);
}

public JsonPathValue(string path, object value, ValueObjectType type)
{
this.Path = path;
this.Value = new ValueWrapper(value, type);
}

public JsonPathValue(string path, IPhrase value)
{
this.Path = path;
this.Value = new ValueWrapper(value);
}

public JsonPathValue(string path, ValueWrapper value)
{
this.Path = path;
this.Value = value;
}

#endregion

#region Convenience

public static JsonPathValue From(string path, string tableName, string columnName)
{
return new JsonPathValue(path, tableName, columnName);
}

public static JsonPathValue From(string path, string column)
{
return new JsonPathValue(path, column);
}

public static JsonPathValue From(string path, object value, ValueObjectType type)
{
return new JsonPathValue(path, value, type);
}

public static JsonPathValue From(string path, IPhrase value)
{
return new JsonPathValue(path, value);
}

public static JsonPathValue From(string path, ValueWrapper value)
{
return new JsonPathValue(path, value);
}

#endregion

#region Utility

internal static List<string> PathParts(string path)
{
List<string> parts = new List<string>();

bool inProp = true; // Starts with a $
bool isEscaped = false;
bool inArray = false;
bool isQuoted = false;
string part = "";

for (int i = 0, len = path.Length; i < len; i++)
{
char c = path[i];

if (isQuoted)
{
if (isEscaped || c != '"')
{
part += c;
}

if (isEscaped)
{
isEscaped = false;
}
else
{
switch (c)
{
case '\\':
isEscaped = true;
break;

case '"':
parts.Add(StringUtils.UnescapeStringLiteral(part));
isQuoted = false;
inProp = false;
break;
}
}

continue;
}

if (inArray)
{
if (c == ']')
{
parts.Add(part);
inArray = false;
}
else
{
part += c;
}

continue;
}

if (inProp)
{
if (c == '.' || c == '[')
{
parts.Add(part);
inProp = false;
}
else
{
if (c == '"' && part.Length == 0)
{
isQuoted = true;
isEscaped = false;
}
else
{
part += c;
}

continue;
}
}

switch (c)
{
case '.':
part = "";
inProp = true;
break;

case '[':
part = "";
inArray = true;
break;
}
}

if (inProp)
{
parts.Add(part);
}

return parts;
}

#endregion
}
}
103 changes: 103 additions & 0 deletions dg.Sql/Sql/Phrases/Json/JsonArray.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Text;
using dg.Sql.Connector;

namespace dg.Sql.Phrases
{
/// <summary>
/// Creates a json array.
/// </summary>
public class JsonArray : IPhrase
{
public List<ValueWrapper> Values;

#region Constructors

public JsonArray()
{
this.Values = new List<ValueWrapper>();
}

public JsonArray(params ValueWrapper[] values)
{
this.Values = new List<ValueWrapper>(values);
}

public JsonArray(IEnumerable<ValueWrapper> values)
{
this.Values = values == null ? new List<ValueWrapper>() : new List<ValueWrapper>(values);
}

public JsonArray(params object[] values)
{
this.Values = new List<ValueWrapper>(values.Length);
foreach (var val in values)
this.Values.Add(ValueWrapper.From(val, ValueObjectType.Value));
}

public JsonArray(params string[] values)
{
this.Values = new List<ValueWrapper>(values.Length);
foreach (var val in values)
this.Values.Add(ValueWrapper.From(val, ValueObjectType.Value));
}

public JsonArray(params Int64[] values)
{
this.Values = new List<ValueWrapper>(values.Length);
foreach (var val in values)
this.Values.Add(ValueWrapper.From(val, ValueObjectType.Value));
}

public JsonArray(params Int32[] values)
{
this.Values = new List<ValueWrapper>(values.Length);
foreach (var val in values)
this.Values.Add(ValueWrapper.From(val, ValueObjectType.Value));
}

#endregion

public string BuildPhrase(ConnectorBase conn, Query relatedQuery = null)
{
switch (conn.TYPE)
{
case ConnectorBase.SqlServiceType.MYSQL:
{
var sb = new StringBuilder();
sb.Append("JSON_ARRAY(");
bool first = true;
foreach (var val in Values)
{
if (first) first = false;
else sb.Append(",");
sb.Append(val.Build(conn, relatedQuery));
}
sb.Append(")");

return sb.ToString();
}

case ConnectorBase.SqlServiceType.POSTGRESQL:
{
var sb = new StringBuilder();
sb.Append("json_build_array(");
bool first = true;
foreach (var val in Values)
{
if (first) first = false;
else sb.Append(",");
sb.Append(val.Build(conn, relatedQuery));
}
sb.Append(")");

return sb.ToString();
}

default:
throw new NotSupportedException("JsonExtract is not supported by current DB type");
}
}
}
}
Loading

0 comments on commit ea6af58

Please sign in to comment.