Skip to content

Commit

Permalink
migrate procedure return value support linq2db/linq2db#1905
Browse files Browse the repository at this point in the history
  • Loading branch information
MaceWindu committed Oct 3, 2019
1 parent 4fe8d44 commit e68a801
Showing 1 changed file with 36 additions and 13 deletions.
49 changes: 36 additions & 13 deletions Source/SchemaAndCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
code
.Append($" {p.MemberName}(")
.Append(p.Parameters
.Where (pr => !pr.IsResult)
.Select(pr => $"{(pr.IsOut ? pr.IsIn ? "ref " : "out " : "")}{pr.ParameterType} {pr.ParameterName}")
.Where (pr => !pr.IsResult || !p.IsFunction)
.Select(pr => $"{(pr.IsOut || pr.IsResult ? pr.IsIn ? "ref " : "out " : "")}{pr.ParameterType} {pr.ParameterName}")
.Join(", "))
.AppendLine(")")
.AppendLine(" {")
Expand All @@ -294,13 +294,14 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
}
else if (p.IsFunction)
{
// aggregate and scalar functions branch
code.AppendLine(" throw new InvalidOperationException();");
}
else
{
var inputParameters = p.Parameters.Where(pp => pp.IsIn) .ToList();
var outputParameters = p.Parameters.Where(pp => pp.IsOut) .ToList();
var inOrOutputParameters = p.Parameters.Where(pp => pp.IsIn || pp.IsOut).ToList();
var inputParameters = p.Parameters.Where(pp => pp.IsIn) .ToList();
var outputParameters = p.Parameters.Where(pp => pp.IsOut || pp.IsResult) .ToList();
var inOrOutputParameters = p.Parameters.Where(pp => pp.IsIn || pp.IsOut || pp.IsResult).ToList();

spName += inOrOutputParameters.Count == 0 ? ");" : ",";

Expand All @@ -310,7 +311,7 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
while (p.Parameters.Any(pp => pp.ParameterName == retName))
retName = "__ret__" + ++retNo;

var hasOut = outputParameters.Any(pr => pr.IsOut);
var hasOut = outputParameters.Any(pr => pr.IsOut || pr.IsResult);
var prefix = hasOut ? $"var {retName} =" : "return";

if (p.ResultTable == null)
Expand Down Expand Up @@ -361,16 +362,16 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
var pr = inOrOutputParameters[i];

var str = string.Format(
!pr.IsIn && pr.IsOut
!pr.IsIn && (pr.IsOut || pr.IsResult)
? " new DataParameter({0}, null, DataType.{2})"
: " new DataParameter({0}, {1}, DataType.{2})",
CSharpTools.ToStringLiteral(pr.SchemaName),
pr.ParameterName,
pr.DataType);

if (pr.IsOut)
if (pr.IsOut || pr.IsResult)
{
str += " { Direction = " + (pr.IsIn ? "ParameterDirection.InputOutput" : "ParameterDirection.Output");
str += " { Direction = " + (pr.IsIn ? "ParameterDirection.InputOutput" : (pr.IsResult ? "ParameterDirection.ReturnValue" : "ParameterDirection.Output"));

if (pr.Size != null && pr.Size.Value != 0)
str += ", Size = " + pr.Size.Value;
Expand All @@ -389,7 +390,7 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
{
code.AppendLine();

foreach (var pr in p.Parameters.Where(_ => _.IsOut))
foreach (var pr in p.Parameters.Where(_ => _.IsOut || _.IsResult))
{
var str = $" {pr.ParameterName} = Converter.ChangeTypeTo<{pr.ParameterType}>(((IDbDataParameter)this.Command.Parameters[\"{pr.SchemaName}\"]).Value);";
code.AppendLine(str);
Expand Down Expand Up @@ -452,14 +453,14 @@ ExplorerItem GetProcedures(string header, ExplorerIcon icon, List<ProcedureSchem
{
DragText = $"{p.MemberName}(" +
p.Parameters
.Where (pr => !pr.IsResult)
.Select(pr => $"{(pr.IsOut ? pr.IsIn ? "ref " : "out " : "")}{pr.ParameterName}")
.Where (pr => !pr.IsResult || !p.IsFunction)
.Select(pr => $"{(pr.IsOut || pr.IsResult ? (pr.IsIn ? "ref " : "out ") : "")}{pr.ParameterName}")
.Join(", ") +
")",
SqlName = sprocSqlName,
IsEnumerable = p.ResultTable != null,
Children = p.Parameters
.Where (pr => !pr.IsResult)
.Where (pr => !pr.IsResult || !p.IsFunction)
.Select(pr =>
new ExplorerItem(
$"{pr.ParameterName} ({pr.ParameterType})",
Expand Down Expand Up @@ -697,6 +698,28 @@ void ConvertSchema(string typeName)

foreach (var procedure in _schema.Procedures)
{
// migrate https://github.com/linq2db/linq2db/pull/1905
if (!procedure.IsFunction && ProviderName == LinqToDB.ProviderName.SqlServer)
{
// sql server procedures always have integer return parameter
var name = "@returnValue";
var cnt = 0;
while (procedure.Parameters.Any(_ => _.ParameterName == name))
name = $"@returnValue{cnt++}";

procedure.Parameters.Add(new ParameterSchema()
{
SchemaName = name,
ParameterName = name,
IsResult = true,
DataType = DataType.Int32,
SystemType = typeof(int),
SchemaType = "int",
ParameterType = "int",
ProviderSpecificType = "int"
});
}

procedure.MemberName = GetName(typeNames, procedure.MemberName);

if (procedure.ResultTable != null && !_contextMembers.ContainsKey(procedure.ResultTable))
Expand Down

0 comments on commit e68a801

Please sign in to comment.