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

Commit

Permalink
Add support for x-plat Sql.Cast()
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Mar 28, 2018
1 parent e5ab084 commit b6ec56b
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/ServiceStack.OrmLite.MySql/MySqlDialectProviderBase.cs
Expand Up @@ -216,6 +216,11 @@ public override string SqlConflict(string sql, string conflictResolution)
public override string SqlCurrency(string fieldOrValue, string currencySymbol) =>
SqlConcat(new[] { "'" + currencySymbol + "'", "cast(" + fieldOrValue + " as decimal(15,2))" });

public override string SqlCast(object fieldOrValue, string castAs) =>
castAs == Sql.VARCHAR
? $"CAST({fieldOrValue} AS CHAR(1000))"
: $"CAST({fieldOrValue} AS {castAs})";

protected DbConnection Unwrap(IDbConnection db)
{
return (DbConnection)db.ToDbConnection();
Expand Down
Expand Up @@ -559,6 +559,9 @@ public override string SqlConflict(string sql, string conflictResolution)
? fieldOrValue + "::text::money::text"
: "replace(" + fieldOrValue + "::text::money::text,'$','" + currencySymbol + "')";

public override string SqlCast(object fieldOrValue, string castAs) =>
$"{fieldOrValue}::{castAs}";

protected NpgsqlConnection Unwrap(IDbConnection db)
{
return (NpgsqlConnection)db.ToDbConnection();
Expand Down
3 changes: 3 additions & 0 deletions src/ServiceStack.OrmLite.SqlServer/SqlServer2016Expression.cs
Expand Up @@ -28,6 +28,9 @@ protected override object VisitSqlMethodCall(MethodCallExpression m)
case nameof(Sql.As):
statement = $"{quotedColName} AS {DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))}";
break;
case nameof(Sql.Cast):
statement = DialectProvider.SqlCast(quotedColName, args[0].ToString());
break;
case nameof(Sql.Sum):
case nameof(Sql.Count):
case nameof(Sql.Min):
Expand Down
Expand Up @@ -556,6 +556,11 @@ public override string GetLoadChildrenSubSelect<From>(SqlExpression<From> expr)
? "OFFSET " + offset.GetValueOrDefault() + " ROWS FETCH NEXT " + rows + " ROWS ONLY"
: "OFFSET " + offset.GetValueOrDefault(int.MaxValue) + " ROWS";

public override string SqlCast(object fieldOrValue, string castAs) =>
castAs == Sql.VARCHAR
? $"CAST({fieldOrValue} AS VARCHAR(MAX))"
: $"CAST({fieldOrValue} AS {castAs})";

protected SqlConnection Unwrap(IDbConnection db) => (SqlConnection)db.ToDbConnection();

protected SqlCommand Unwrap(IDbCommand cmd) => (SqlCommand)cmd.ToDbCommand();
Expand Down
4 changes: 4 additions & 0 deletions src/ServiceStack.OrmLite/Expressions/Sql.cs
Expand Up @@ -7,6 +7,8 @@ namespace ServiceStack.OrmLite
{
public static partial class Sql
{
public static string VARCHAR = nameof(VARCHAR);

public static List<object> Flatten(IEnumerable list)
{
var ret = new List<object>();
Expand Down Expand Up @@ -68,6 +70,8 @@ public static List<object> Flatten(IEnumerable list)

public static T Custom<T>(string customSql) => default(T);

public static string Cast(object value, string castAs) => $"CAST({value} AS {castAs})";

public const string EOT= "0 EOT";
}

Expand Down
3 changes: 3 additions & 0 deletions src/ServiceStack.OrmLite/Expressions/SqlExpression.cs
Expand Up @@ -2351,6 +2351,9 @@ protected virtual object VisitSqlMethodCall(MethodCallExpression m)
case nameof(Sql.As):
statement = $"{quotedColName} AS {DialectProvider.GetQuotedColumnName(RemoveQuoteFromAlias(args[0].ToString()))}";
break;
case nameof(Sql.Cast):
statement = DialectProvider.SqlCast(quotedColName, args[0].ToString());
break;
case nameof(Sql.Sum):
case nameof(Sql.Count):
case nameof(Sql.Min):
Expand Down
1 change: 1 addition & 0 deletions src/ServiceStack.OrmLite/IOrmLiteDialectProvider.cs
Expand Up @@ -220,5 +220,6 @@ public interface IOrmLiteDialectProvider
string SqlCurrency(string fieldOrValue, string currencySymbol);
string SqlBool(bool value);
string SqlLimit(int? offset = null, int? rows = null);
string SqlCast(object fieldOrValue, string castAs);
}
}
2 changes: 2 additions & 0 deletions src/ServiceStack.OrmLite/OrmLiteDialectProviderBase.cs
Expand Up @@ -1595,6 +1595,8 @@ protected virtual string ToDropColumnStatement(Type modelType, string columnName
: offset == null
? "LIMIT " + rows
: "LIMIT " + rows.GetValueOrDefault(int.MaxValue) + " OFFSET " + offset;

public virtual string SqlCast(object fieldOrValue, string castAs) => $"CAST({fieldOrValue} AS {castAs})";

//Async API's, should be overrided by Dialect Providers to use .ConfigureAwait(false)
//Default impl below uses TaskAwaiter shim in async.cs
Expand Down
25 changes: 23 additions & 2 deletions tests/ServiceStack.OrmLite.Tests/SqlDialectTests.cs
@@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using ServiceStack.DataAnnotations;
using ServiceStack.Text;
Expand All @@ -15,7 +16,7 @@ public class Sqltest

public class SqlDialectTests : OrmLiteTestBase
{
//public SqlDialectTests() : base(Dialect.PostgreSql) {}
// public SqlDialectTests() : base(Dialect.SqlServer2008) {}

[Test]
public void Does_concat_values()
Expand All @@ -36,6 +37,26 @@ public void Does_concat_values()
}
}

[Test]
public void Does_concat_values_in_SqlExpression()
{
using (var db = OpenDbConnection())
{
db.DropAndCreateTable<Sqltest>();

db.Insert(new Sqltest { Value = 123.456, Bool = true });

var results = db.Select<Dictionary<string, object>>(db.From<Sqltest>()
.Select(x => new {
x.Id,
text = Sql.As(Sql.Cast(x.Id, Sql.VARCHAR) + " : " + Sql.Cast(x.Value, Sql.VARCHAR) + " : " + Sql.Cast(x.Bool, Sql.VARCHAR) + " string", "text")
}));

Assert.That(results[0]["text"], Is.EqualTo("1 : 123.456 : 1 string")
.Or.EqualTo("1 : 123.456 : true string"));
}
}

[Test]
public void Does_format_currency()
{
Expand Down

0 comments on commit b6ec56b

Please sign in to comment.