Skip to content

Commit

Permalink
Merge pull request #13 from linq2db/linq2db_2.5_support
Browse files Browse the repository at this point in the history
Updating to support linq2db 2.5
  • Loading branch information
MaceWindu authored Nov 5, 2018
2 parents 5b9cba2 + 52bf8f7 commit 57dff69
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 12 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
; What is EditorConfig? http://editorconfig.org/

root = true

; use tabs identation for all files
[*]
indent_style = tab
insert_final_newline = true
Binary file removed Redist/SAPHana/Sap.Data.Hana.v4.5.dll
Binary file not shown.
4 changes: 3 additions & 1 deletion Source/DriverHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public static bool ShowConnectionDialog(DataContextDriver driver, IConnectionInf
model.EncryptConnectionString = cxInfo.DatabaseInfo.EncryptCustomCxString;
model.Pluralize = !cxInfo.DynamicSchemaOptions.NoPluralization;
model.Capitalize = !cxInfo.DynamicSchemaOptions.NoCapitalization;
model.IncludeRoutines = !isNewConnection && !cxInfo.DynamicSchemaOptions.ExcludeRoutines;
//model.IncludeRoutines = !isNewConnection && !cxInfo.DynamicSchemaOptions.ExcludeRoutines;
model.IncludeRoutines = cxInfo.DriverData.Element("excludeRoutines")?.Value.ToLower() != "true";
model.ConnectionString = cxInfo.DatabaseInfo.CustomCxString.IsNullOrWhiteSpace() ? (string)cxInfo.DriverData.Element("connectionString") : cxInfo.DatabaseInfo.CustomCxString;
model.IncludeSchemas = cxInfo.DriverData.Element("includeSchemas") ?.Value;
model.ExcludeSchemas = cxInfo.DriverData.Element("excludeSchemas") ?.Value;
Expand All @@ -58,6 +59,7 @@ public static bool ShowConnectionDialog(DataContextDriver driver, IConnectionInf

cxInfo.DriverData.SetElementValue("providerName", providerName);
cxInfo.DriverData.SetElementValue("connectionString", null);
cxInfo.DriverData.SetElementValue("excludeRoutines", !model.IncludeRoutines ? "true" : "false");
cxInfo.DriverData.SetElementValue("includeSchemas", model.IncludeSchemas. IsNullOrWhiteSpace() ? null : model.IncludeSchemas);
cxInfo.DriverData.SetElementValue("excludeSchemas", model.ExcludeSchemas. IsNullOrWhiteSpace() ? null : model.ExcludeSchemas);
cxInfo.DriverData.SetElementValue("includeCatalogs", model.IncludeCatalogs.IsNullOrWhiteSpace() ? null : model.IncludeSchemas);
Expand Down
6 changes: 6 additions & 0 deletions Source/LINQPadDataConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ static LINQPadDataConnection()
public LINQPadDataConnection()
{
Init();
InitMappingSchema();
}

public LINQPadDataConnection(string providerName, string connectionString)
: base(ProviderHelper.GetProvider(providerName).GetDataProvider(connectionString), connectionString)
{
Init();
InitMappingSchema();
}

public LINQPadDataConnection(IConnectionInfo cxInfo)
Expand All @@ -37,6 +39,10 @@ public LINQPadDataConnection(IConnectionInfo cxInfo)
{
}

protected virtual void InitMappingSchema()
{
}

static void Init()
{
TurnTraceSwitchOn();
Expand Down
2 changes: 2 additions & 0 deletions Source/LinqToDBDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Net.NetworkInformation;

namespace LinqToDB.LINQPad
{
Expand Down Expand Up @@ -68,6 +69,7 @@ public override List<ExplorerItem> GetSchemaAndBuildAssembly(
MetadataReference.CreateFromFile(typeof(IDbConnection). Assembly.Location),
MetadataReference.CreateFromFile(typeof(DataConnection). Assembly.Location),
MetadataReference.CreateFromFile(typeof(LINQPadDataConnection).Assembly.Location),
MetadataReference.CreateFromFile(typeof(PhysicalAddress) .Assembly.Location),
};

references.AddRange(gen.References.Select(r => MetadataReference.CreateFromFile(r)));
Expand Down
125 changes: 125 additions & 0 deletions Source/SchemaAndCodeGenerator.PostgreSQL.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using LinqToDB.SchemaProvider;
using System.Collections.Generic;
using System.Linq;

namespace LinqToDB.LINQPad
{
partial class SchemaAndCodeGenerator
{
private void PreprocessPostgreSQLSchema()
{
PgSqlFixTableFunctions();
PgSqlFixRecordResultFunctions();
PgSqlFixVoidFunctions();
PgSqlFixFunctionNames();
}

void PgSqlFixRecordResultFunctions()
{
var mappings = new List<(string, IList<string>)>();

foreach (var proc in _schema.Procedures
.Where(p => p.IsFunction && !p.IsAggregateFunction && !p.IsTableFunction && p.Parameters.Any(pr => pr.IsOut)))
{
if (proc.Parameters.Count(pr => pr.IsOut) > 1)
{
var result = new TableSchema()
{
TypeName = SchemaProviderBase.ToValidName(proc.ProcedureName + "Result"),
Columns = new List<ColumnSchema>(),
IsProcedureResult = true,
ForeignKeys = new List<ForeignKeySchema>()
};

_schema.Tables.Add(result);
proc.ResultTable = result;

proc.Parameters.Add(new ParameterSchema()
{
IsResult = true,
ParameterType = result.TypeName
});

var resultMappings = new List<string>();
mappings.Add((result.TypeName, resultMappings));

foreach (var outParam in proc.Parameters.Where(_ => _.IsOut))
{
//outParam.ParameterType, outParam.ParameterName, null, null
result.Columns.Add(new ColumnSchema()
{
MemberType = outParam.ParameterType,
MemberName = outParam.ParameterName
});

resultMappings.Add($"{outParam.ParameterName} = ({outParam.ParameterType})tuple[{resultMappings.Count}]");

if (outParam.IsIn)
outParam.IsOut = false;
}

proc.Parameters = proc.Parameters.Where(_ => !_.IsOut).ToList();

}
else // one parameter
{
var param = proc.Parameters.Single(_ => _.IsOut);
proc.Parameters.Remove(param);
proc.Parameters.Add(new ParameterSchema()
{
IsResult = true,
ParameterType = param.ParameterType
});
}
}

if (mappings.Count > 0)
{
Code
.AppendLine(" protected override void InitMappingSchema()")
.AppendLine(" {");

foreach (var (typeName, valueMappings) in mappings)
{
Code.AppendLine($" MappingSchema.SetConvertExpression<object[], {typeName}>(tuple => new {typeName}() {{ {string.Join(", ", valueMappings)} }});");
}

Code
.AppendLine(" }");
}
}

void PgSqlFixFunctionNames()
{
foreach (var proc in _schema.Procedures)
{
if (proc.ProcedureName.Any(char.IsUpper))
proc.ProcedureName = "\"" + proc.ProcedureName + "\"";
}
}

void PgSqlFixTableFunctions()
{
foreach (var proc in _schema.Procedures
.Where(p => p.IsTableFunction && p.Parameters.Any(pr => pr.IsOut)))
{
proc.Parameters = proc.Parameters.Where(pr => !pr.IsOut).ToList();
}
}

void PgSqlFixVoidFunctions()
{
// generated functions should return object for void-typed functions
foreach (var proc in _schema.Procedures
.Where(p => p.IsFunction && !p.IsTableFunction && !p.Parameters.Any(pr => pr.IsResult)))
{
proc.Parameters.Add(new ParameterSchema()
{
IsResult = true,
ParameterType = "object",
SystemType = typeof(object)
});
}
}
}
}
82 changes: 75 additions & 7 deletions Source/SchemaAndCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

namespace LinqToDB.LINQPad
{
class SchemaAndCodeGenerator
partial class SchemaAndCodeGenerator
{
public SchemaAndCodeGenerator(IConnectionInfo cxInfo)
{
Expand Down Expand Up @@ -45,6 +45,21 @@ public SchemaAndCodeGenerator(IConnectionInfo cxInfo)

public readonly StringBuilder Code = new StringBuilder();

private HashSet<string> _existingMemberNames = new HashSet<string>(StringComparer.InvariantCulture);

private static HashSet<string> _keyWords = new HashSet<string>
{
"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked",
"class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum",
"event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto",
"if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", "new",
"null", "object", "operator", "out", "override", "params", "private", "protected", "public", "readonly",
"ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "struct", "switch",
"this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort",
"using", "virtual", "volatile", "void", "while", "namespace", "string"
};


public IEnumerable<ExplorerItem> GetItemsAndCode(string nameSpace, string typeName)
{
var connectionString = _cxInfo.DatabaseInfo.CustomCxString;
Expand Down Expand Up @@ -72,6 +87,8 @@ public IEnumerable<ExplorerItem> GetItemsAndCode(string nameSpace, string typeNa
var excludeCatalogs = (string)_cxInfo.DriverData.Element("excludeCatalogs");
if (excludeCatalogs != null) options.ExcludedCatalogs = excludeCatalogs.Split(',', ';');

options.GetProcedures = (string)_cxInfo.DriverData.Element("excludeRoutines") != "true";

_schema = _dataProvider.GetSchemaProvider().GetSchema(db, options);

ConvertSchema(typeName);
Expand All @@ -87,8 +104,14 @@ public IEnumerable<ExplorerItem> GetItemsAndCode(string nameSpace, string typeNa
.AppendLine("using LinqToDB.Common;")
.AppendLine("using LinqToDB.Data;")
.AppendLine("using LinqToDB.Mapping;")
.AppendLine("using System.Net.NetworkInformation;")
;

if (_schema.Procedures.Any(_ => _.IsAggregateFunction))
Code
.AppendLine("using System.Linq.Expressions;")
;

if (_schema.ProviderSpecificTypeNamespace.NotNullNorWhiteSpace())
Code.AppendLine($"using {_schema.ProviderSpecificTypeNamespace};");

Expand Down Expand Up @@ -117,6 +140,11 @@ public IEnumerable<ExplorerItem> GetItemsAndCode(string nameSpace, string typeNa
.AppendLine( " }")
;

if (ProviderName == LinqToDB.ProviderName.PostgreSQL)
{
PreprocessPostgreSQLSchema();
}

var schemas =
(
from t in
Expand Down Expand Up @@ -200,9 +228,11 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
{
code.AppendLine();

var spName = $"\"{sprocSqlName.Replace("\"", "\\\"")}\"";

if (p.IsTableFunction)
{
code.Append($" [Sql.TableFunction(Name=\"{p.ProcedureName}\"");
code.Append($" [Sql.TableFunction(Name=\"{p.ProcedureName.Replace("\"", "\\\"")}\"");

if (p.SchemaName != null)
code.Append($", Schema=\"{p.SchemaName}\")");
Expand All @@ -212,10 +242,36 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
.Append($" public ITable<{p.ResultTable?.TypeName}>")
;
}
else if (p.IsAggregateFunction)
{
var inputs = p.Parameters.Where(pr => !pr.IsResult).ToArray();
p.Parameters.RemoveAll(parameter => !parameter.IsResult);

p.Parameters.Add(new ParameterSchema()
{
ParameterType = "IEnumerable<TSource>",
ParameterName = "src"
});

foreach (var input in inputs.Where(pr => !pr.IsResult))
p.Parameters.Add(new ParameterSchema()
{
ParameterType = $"Expression<Func<TSource, {input.ParameterType}>>",
ParameterName = $"{input.ParameterName}"
});

p.MemberName += "<TSource>";

code
.Append($" [Sql.Function(Name={spName}, ServerSideOnly=true, IsAggregate = true")
.Append(inputs.Length > 0 ? $", ArgIndices = new[] {{ {string.Join(", ", Enumerable.Range(0, inputs.Length))} }}" : string.Empty)
.AppendLine(")]")
.Append($" public static {p.Parameters.Single(pr => pr.IsResult).ParameterType}");
}
else if (p.IsFunction)
{
code
.AppendLine($" [Sql.Function(Name=\"{sprocSqlName}\", ServerSideOnly=true)]")
.AppendLine($" [Sql.Function(Name={spName}, ServerSideOnly=true)]")
.Append ($" public static {p.Parameters.Single(pr => pr.IsResult).ParameterType}");
}
else
Expand Down Expand Up @@ -251,8 +307,6 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName)
}
else
{
var spName = $"\"{sprocSqlName.Replace("\"", "\\\"")}\"";

var inputParameters = p.Parameters.Where(pp => pp.IsIn). ToList();
var outputParameters = p.Parameters.Where(pp => pp.IsOut).ToList();

Expand Down Expand Up @@ -437,6 +491,8 @@ void CodeTable(StringBuilder classCode, TableSchema table, bool addTableAttribut
{
classCode.AppendLine();

table.TypeName = GetName(_existingMemberNames, table.TypeName);

if (addTableAttribute)
{
classCode.Append($" [Table(Name=\"{table.TableName}\"");
Expand All @@ -459,7 +515,7 @@ void CodeTable(StringBuilder classCode, TableSchema table, bool addTableAttribut
.Append(c.IsNullable ? "Nullable" : "NotNull");

if (c.IsPrimaryKey) classCode.Append($", PrimaryKey({c.PrimaryKeyOrder})");
if (c.IsIdentity) classCode.Append(", Identity");
if (c.IsIdentity) classCode.Append(", Identity");

classCode.AppendLine("]");

Expand Down Expand Up @@ -655,6 +711,11 @@ void ConvertSchema(string typeName)
column.MemberName = GetName(classMemberNames, memberName);
}
}

foreach (var parameter in procedure.Parameters)
{
parameter.ParameterName = ConvertToCompilable(parameter.ParameterName, false);
}
}
}

Expand Down Expand Up @@ -696,7 +757,14 @@ from c in name.TrimStart('@')
}
}

return sb.ToString();
name = sb.ToString();

if (_keyWords.Contains(name) || name.StartsWith("__"))
{
name = '@' + name;
}

return name;
}
}
}
6 changes: 3 additions & 3 deletions Source/linq2db.LINQPad.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@
<Reference Include="JetBrains.Annotations, Version=2018.2.1.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
<HintPath>..\packages\JetBrains.Annotations.2018.2.1\lib\net20\JetBrains.Annotations.dll</HintPath>
</Reference>
<Reference Include="linq2db, Version=2.2.0.0, Culture=neutral, PublicKeyToken=e41013125f9e410a, processorArchitecture=MSIL">
<HintPath>..\packages\linq2db.2.2.0\lib\net45\linq2db.dll</HintPath>
<Reference Include="linq2db, Version=2.5.1.0, Culture=neutral, PublicKeyToken=e41013125f9e410a, processorArchitecture=MSIL">
<HintPath>..\packages\linq2db.2.5.1\lib\net45\linq2db.dll</HintPath>
</Reference>
<Reference Include="LINQPad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=21353812cd2a2db5, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
Expand Down Expand Up @@ -188,6 +188,7 @@
<Compile Include="Pluralization.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProviderHelper.cs" />
<Compile Include="SchemaAndCodeGenerator.PostgreSQL.cs" />
<Compile Include="SchemaGenerator.cs" />
<Compile Include="SchemaAndCodeGenerator.cs" />
<Compile Include="SqlServerTypes\Loader.cs" />
Expand Down Expand Up @@ -276,7 +277,6 @@
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"

xcopy /s /y "$(SolutionDir)Redist\IBM\*.dll" "$(TargetDir)"
xcopy /s /y "$(SolutionDir)Redist\SAPHana\*.dll" "$(TargetDir)"
xcopy /s /y "$(SolutionDir)Redist\Sybase\*.dll" "$(TargetDir)"
$(ProjectDir)DevDeploy.bat $(TargetDir)
</PostBuildEvent>
Expand Down
Loading

0 comments on commit 57dff69

Please sign in to comment.