Skip to content

Commit

Permalink
Merge pull request #389 from pietervp/master
Browse files Browse the repository at this point in the history
Fix T4 templates: MSSQL Multiple PK + VB.Net code generation
  • Loading branch information
ili committed Dec 8, 2016
2 parents 944ff89 + 179a9f3 commit a875bd3
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 118 deletions.
89 changes: 89 additions & 0 deletions Source/Templates/BLToolkit.ttinclude
Expand Up @@ -284,6 +284,95 @@ static Action<GeneratedTextTransformation> RenderUsing = tt =>
}
};

static Func<string> FreeTextTemplate = () =>
{
return @"
#region FreeTextTable

public class FreeTextKey<T>
{
public T Key;
public int Rank;
}

class FreeTextTableExpressionAttribute : TableExpressionAttribute
{
public FreeTextTableExpressionAttribute()
: base("""")
{
}

public override void SetTable(SqlTable table, MemberInfo member, IEnumerable<Expression> expArgs, IEnumerable<ISqlExpression> sqlArgs)
{
var aargs = sqlArgs.ToArray();
var arr = ConvertArgs(member, aargs).ToList();
var method = (MethodInfo)member;
var sp = new MsSql2008SqlProvider();

{
var ttype = method.GetGenericArguments()[0];
var tbl = new SqlTable(ttype);

var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString();
var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString();
var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString();

var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName);

arr.Add(new SqlExpression(name.ToString(), Precedence.Primary));
}

{
var field = ((ConstantExpression)expArgs.First()).Value;

if (field is string)
{
arr[0] = new SqlExpression(field.ToString(), Precedence.Primary);
}
else if (field is LambdaExpression)
{
var body = ((LambdaExpression)field).Body;

if (body is MemberExpression)
{
var name = ((MemberExpression)body).Member.Name;

name = sp.Convert(name, ConvertType.NameToQueryField).ToString();

arr[0] = new SqlExpression(name, Precedence.Primary);
}
}
}

table.SqlTableType = SqlTableType.Expression;
table.Name = ""FREETEXTTABLE({6}, {2}, {3}) {1}"";
table.TableArguments = arr.ToArray();
}
}

[FreeTextTableExpressionAttribute]
public Table<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(string field, string text)
{
return this.GetTable<FreeTextKey<TKey>>(
this,
((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
field,
text);
}

[FreeTextTableExpressionAttribute]
public Table<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(Expression<Func<TTable,string>> fieldSelector, string text)
{
return this.GetTable<FreeTextKey<TKey>>(
this,
((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
fieldSelector,
text);
}

#endregion";
};

Action<GeneratedTextTransformation> BeforeGenerateModel = _ => {};
Action<GeneratedTextTransformation> AfterGenerateModel = _ => {};

Expand Down
135 changes: 24 additions & 111 deletions Source/Templates/MSSQL.ttinclude
Expand Up @@ -231,33 +231,30 @@ private void LoadServerMetadata()
// Load FKs.
//
s = @"
SELECT
rc.CONSTRAINT_NAME as Name,
fk.TABLE_CATALOG + '.' + fk.TABLE_SCHEMA + '.' + fk.TABLE_NAME as ThisTable,
fk.COLUMN_NAME as ThisColumn,
pk.TABLE_CATALOG + '.' + pk.TABLE_SCHEMA + '.' + pk.TABLE_NAME as OtherTable,
pk.COLUMN_NAME as OtherColumn,
cu.ORDINAL_POSITION as Ordinal
FROM
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE fk
ON
rc.CONSTRAINT_CATALOG = fk.CONSTRAINT_CATALOG AND
rc.CONSTRAINT_SCHEMA = fk.CONSTRAINT_SCHEMA AND
rc.CONSTRAINT_NAME = fk.CONSTRAINT_NAME
JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE pk
ON
rc.UNIQUE_CONSTRAINT_CATALOG = pk.CONSTRAINT_CATALOG AND
rc.UNIQUE_CONSTRAINT_SCHEMA = pk.CONSTRAINT_SCHEMA AND
rc.UNIQUE_CONSTRAINT_NAME = pk.CONSTRAINT_NAME
JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu
SELECT
kc.name as UNIQUE_CONSTRAINT_NAME,
f.name AS Name,
DB_NAME() + '.' + SCHEMA_NAME (thisobj.schema_id) + '.' + OBJECT_NAME(f.parent_object_id) AS ThisTable,
COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ThisColumn,
DB_NAME() + '.' + SCHEMA_NAME (otherobj.schema_id) + '.' + OBJECT_NAME (f.referenced_object_id) AS OtherTable,
COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS OtherColumn,
cu.ORDINAL_POSITION AS Ordinal
FROM
sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
LEFT JOIN sys.key_constraints kc
ON kc.parent_object_id = f.referenced_object_id AND kc.type = 'PK'
INNER JOIN sys.objects thisobj
ON thisobj.object_id = f.parent_object_id
INNER JOIN sys.objects otherobj
ON otherobj.object_id = f.referenced_object_id
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu
ON
rc.CONSTRAINT_CATALOG = cu.CONSTRAINT_CATALOG AND
rc.CONSTRAINT_SCHEMA = cu.CONSTRAINT_SCHEMA AND
rc.CONSTRAINT_NAME = cu.CONSTRAINT_NAME
DB_NAME() = cu.CONSTRAINT_CATALOG AND
SCHEMA_NAME(thisobj.schema_id) = cu.CONSTRAINT_SCHEMA AND
f.Name = cu.CONSTRAINT_NAME AND
cu.COLUMN_NAME = COL_NAME(fc.parent_object_id, fc.parent_column_id)
{0}
ORDER BY
ThisTable,
Expand Down Expand Up @@ -332,91 +329,7 @@ private void LoadServerMetadata()
{
mssqlAfterWriteTableProperty(tt);

tt.WriteLine(@"
#region FreeTextTable

public class FreeTextKey<T>
{
public T Key;
public int Rank;
}

class FreeTextTableExpressionAttribute : TableExpressionAttribute
{
public FreeTextTableExpressionAttribute()
: base("""")
{
}

public override void SetTable(SqlTable table, MemberInfo member, IEnumerable<Expression> expArgs, IEnumerable<ISqlExpression> sqlArgs)
{
var aargs = sqlArgs.ToArray();
var arr = ConvertArgs(member, aargs).ToList();
var method = (MethodInfo)member;
var sp = new MsSql2008SqlProvider();

{
var ttype = method.GetGenericArguments()[0];
var tbl = new SqlTable(ttype);

var database = tbl.Database == null ? null : sp.Convert(tbl.Database, ConvertType.NameToDatabase). ToString();
var owner = tbl.Owner == null ? null : sp.Convert(tbl.Owner, ConvertType.NameToOwner). ToString();
var physicalName = tbl.PhysicalName == null ? null : sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString();

var name = sp.BuildTableName(new StringBuilder(), database, owner, physicalName);

arr.Add(new SqlExpression(name.ToString(), Precedence.Primary));
}

{
var field = ((ConstantExpression)expArgs.First()).Value;

if (field is string)
{
arr[0] = new SqlExpression(field.ToString(), Precedence.Primary);
}
else if (field is LambdaExpression)
{
var body = ((LambdaExpression)field).Body;

if (body is MemberExpression)
{
var name = ((MemberExpression)body).Member.Name;

name = sp.Convert(name, ConvertType.NameToQueryField).ToString();

arr[0] = new SqlExpression(name, Precedence.Primary);
}
}
}

table.SqlTableType = SqlTableType.Expression;
table.Name = ""FREETEXTTABLE({6}, {2}, {3}) {1}"";
table.TableArguments = arr.ToArray();
}
}

[FreeTextTableExpressionAttribute]
public Table<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(string field, string text)
{
return this.GetTable<FreeTextKey<TKey>>(
this,
((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
field,
text);
}

[FreeTextTableExpressionAttribute]
public Table<FreeTextKey<TKey>> FreeTextTable<TTable,TKey>(Expression<Func<TTable,string>> fieldSelector, string text)
{
return this.GetTable<FreeTextKey<TKey>>(
this,
((MethodInfo)(MethodBase.GetCurrentMethod())).MakeGenericMethod(typeof(TTable), typeof(TKey)),
fieldSelector,
text);
}

#endregion");
tt.WriteLine(FreeTextTemplate());

};
}
Expand Down
90 changes: 83 additions & 7 deletions Source/Templates/VB.ttinclude
Expand Up @@ -14,10 +14,13 @@ WriteBeginClass = (tt,cl,bc) =>
};
WriteEndClass = tt => WriteLine("End Class");
MakeGenericType = (c,t) => string.Format("{0}(Of {1})", c, t);
WriteTableProperty = (tt,name,pname,maxlen,maxplen) =>
WriteTableProperty = (tt,name,pname,maxlen,maxplen, desc) =>
{
if (char.IsDigit(pname[0]))
pname = "C" + pname;

WriteLine("");
WriteLine("Public ReadOnly Property {0}(){1} As Table(Of {2})", pname, LenDiff(maxplen, pname), name);
WriteLine("Public ReadOnly Property [{0}](){1} As Table(Of {2})", pname, LenDiff(maxplen, pname), name);
WriteLine("\tGet");
WriteLine("\t\tReturn Me.GetTable(Of {0})()", name);
WriteLine("\tEnd Get");
Expand All @@ -29,7 +32,7 @@ WriteAttributeLine = tt => {};
RenderColumn = (tt,c,maxLens,attrs) =>
{
WriteLine("");

var type = MakeType(c.Type);

if (!tt.RenderField)
Expand All @@ -41,10 +44,10 @@ RenderColumn = (tt,c,maxLens,attrs) =>
WriteLine("<{0}> _", string.Join(", ", attrs).Replace("=", ":="));

if (tt.RenderField)
WriteLine("Public {0} As {1}", c.MemberName, type);
WriteLine("Public [{0}] As {1}", c.MemberName, type);
else
{
WriteLine("Public Property {0} As {1}", c.MemberName, type);
WriteLine("Public Property [{0}] As {1}", c.MemberName, type);
WriteLine("\tGet");
WriteLine("\t\tReturn Me._{0}", c.MemberName);
WriteLine("\tEnd Get");
Expand Down Expand Up @@ -73,10 +76,10 @@ RenderForeignKey = (tt,key) =>
string.Join(", ", (from c in key.OtherColumns select c.MemberName).ToArray()));

if (RenderField)
WriteLine("Public {0} As {1}", key.MemberName, type);
WriteLine("Public [{0}] As {1}", key.MemberName, type);
else
{
WriteLine("Public Property {0} As {1}", key.MemberName, type);
WriteLine("Public Property [{0}] As {1}", key.MemberName, type);
WriteLine("\tGet");
WriteLine("\t\tReturn Me._{0}", key.MemberName);
WriteLine("\tEnd Get");
Expand Down Expand Up @@ -114,4 +117,77 @@ MakeType = t =>

return t;
};

FreeTextTemplate = () =>
{
return @"
#Region ""FreeTextTable""

Public Class FreeTextKey(Of T)
Public Key As T
Public Rank As Integer
End Class

Private Class FreeTextTableExpressionAttribute
Inherits TableExpressionAttribute
Public Sub New()
MyBase.New("""")
End Sub

Public Overrides Sub SetTable(table As SqlTable, member As MemberInfo, expArgs As IEnumerable(Of Expression), sqlArgs As IEnumerable(Of ISqlExpression))
Dim aargs = sqlArgs.ToArray()
Dim arr = ConvertArgs(member, aargs).ToList()
Dim method = DirectCast(member, MethodInfo)
Dim sp = New MsSql2008SqlProvider()

If True Then
Dim ttype = method.GetGenericArguments()(0)
Dim tbl = New SqlTable(ttype)

Dim database = If(tbl.Database Is Nothing, Nothing, sp.Convert(tbl.Database, ConvertType.NameToDatabase).ToString())
Dim owner = If(tbl.Owner Is Nothing, Nothing, sp.Convert(tbl.Owner, ConvertType.NameToOwner).ToString())
Dim physicalName = If(tbl.PhysicalName Is Nothing, Nothing, sp.Convert(tbl.PhysicalName, ConvertType.NameToQueryTable).ToString())

Dim name = sp.BuildTableName(New StringBuilder(), database, owner, physicalName)

arr.Add(New SqlExpression(name.ToString(), Precedence.Primary))
End If

If True Then
Dim field = DirectCast(expArgs.First(), ConstantExpression).Value

If TypeOf field Is String Then
arr(0) = New SqlExpression(field.ToString(), Precedence.Primary)
ElseIf TypeOf field Is LambdaExpression Then
Dim body = DirectCast(field, LambdaExpression).Body

If TypeOf body Is MemberExpression Then
Dim name = DirectCast(body, MemberExpression).Member.Name

name = sp.Convert(name, ConvertType.NameToQueryField).ToString()

arr(0) = New SqlExpression(name, Precedence.Primary)
End If
End If
End If

table.SqlTableType = SqlTableType.Expression
table.Name = ""FREETEXTTABLE({6}, {2}, {3}) {1}""
table.TableArguments = arr.ToArray()
End Sub
End Class

<FreeTextTableExpressionAttribute> _
Public Function FreeTextTable(Of TTable, TKey)(field As String, text As String) As Table(Of FreeTextKey(Of TKey))
Return Me.GetTable(Of FreeTextKey(Of TKey))(Me, DirectCast(MethodBase.GetCurrentMethod(), MethodInfo).MakeGenericMethod(GetType(TTable), GetType(TKey)), field, text)
End Function

<FreeTextTableExpressionAttribute> _
Public Function FreeTextTable(Of TTable, TKey)(fieldSelector As Expression(Of Func(Of TTable, String)), text As String) As Table(Of FreeTextKey(Of TKey))
Return Me.GetTable(Of FreeTextKey(Of TKey))(Me, DirectCast(MethodBase.GetCurrentMethod(), MethodInfo).MakeGenericMethod(GetType(TTable), GetType(TKey)), fieldSelector, text)
End Function

#End Region
";
};
#>

0 comments on commit a875bd3

Please sign in to comment.