diff --git a/Source/CSharpTools.cs b/Source/CSharpTools.cs new file mode 100644 index 0000000..d8056ed --- /dev/null +++ b/Source/CSharpTools.cs @@ -0,0 +1,167 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +namespace LinqToDB.LINQPad +{ + // added temporary from https://github.com/linq2db/linq2db/pull/1393 + internal static class CSharpTools + { + /// + /// Reserved words taken from + /// . + /// List actual for C# 7.3. + /// Doesn't contain "using static", + /// + private static readonly ISet _reservedWords + = new HashSet() + { + "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", "namespace", + "new", "null", "object", "operator", "out", "override", "params", "private", + "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", + "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", + "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", + "using", "virtual", "void", "volatile", "while" + }; + + /// + /// Contextual words taken from + /// . + /// List actual for C# 7.3. + /// + private static readonly ISet _contextualWords + = new HashSet() + { + "add", "alias", "ascending", "async", "await", "by", "descending", "dynamic", + "equals", "from", "get", "global", "group", "into", "join", "let", + "nameof", "on", "orderby", "partial", "remove", "select", "set", "unmanaged", + "value", "var", "when", "where", "yield" + }; + + private static readonly ISet _otherCharsCategories; + + private static readonly ISet _startCharCategories; + + static CSharpTools() + { + _startCharCategories = new HashSet() + { + // Lu letter + UnicodeCategory.UppercaseLetter, + // Ll letter + UnicodeCategory.LowercaseLetter, + // Lt letter + UnicodeCategory.TitlecaseLetter, + // Lm letter + UnicodeCategory.ModifierLetter, + // Lo letter + UnicodeCategory.OtherLetter, + // Nl letter + UnicodeCategory.LetterNumber + }; + + _otherCharsCategories = new HashSet(_startCharCategories) + { + // Mn + UnicodeCategory.NonSpacingMark, + // Mc + UnicodeCategory.SpacingCombiningMark, + // Nd + UnicodeCategory.DecimalDigitNumber, + // Pc + UnicodeCategory.ConnectorPunctuation, + // Cf + UnicodeCategory.Format + }; + } + + /// + /// Converts to valid C# identifier. + /// + public static string ToValidIdentifier(string name) + { + if (name == null || name == string.Empty || name == "@") + { + return "_"; + } + + if (_reservedWords.Contains(name) || _contextualWords.Contains(name)) + { + return "@" + name; + } + + if (name.StartsWith("@")) + { + if (_reservedWords.Contains(name.Substring(1)) || _contextualWords.Contains(name.Substring(1))) + { + return name; + } + else + { + name = name.Substring(1); + } + } + + var sb = new StringBuilder(); + + foreach (var chr in name) + { + var cat = CharUnicodeInfo.GetUnicodeCategory(chr); + if (sb.Length == 0 && !_startCharCategories.Contains(cat) && chr != '_') + { + sb.Append("_"); + } + + if (sb.Length != 0 && !_otherCharsCategories.Contains(cat)) + { + sb.Append("_"); + } + else + { + sb.Append(chr); + } + } + + if (sb.Length >= 2 && sb[0] == '_' && sb[1] == '_' && (sb.Length == 2 || sb[2] != '_')) + { + sb.Insert(0, '_'); + } + + return sb.ToString(); + } + + public static string ToStringLiteral(string value) + { + if (value == null) + return "null"; + + var sb = new StringBuilder("\""); + + foreach (var chr in value) + { + switch (chr) + { + case '\t': sb.Append("\\t"); break; + case '\n': sb.Append("\\n"); break; + case '\r': sb.Append("\\r"); break; + case '\\': sb.Append("\\\\"); break; + case '"': sb.Append("\\\""); break; + case '\0': sb.Append("\\0"); break; + case '\u0085': + case '\u2028': + case '\u2029': + sb.Append($"\\u{(ushort)chr:X4}"); break; + default: sb.Append(chr); break; + } + } + + sb.Append('"'); + + return sb.ToString(); + } + } +} diff --git a/Source/LinqToDB.Templates/DataAnnotations.ttinclude b/Source/LinqToDB.Templates/DataAnnotations.ttinclude deleted file mode 100644 index 70f22af..0000000 --- a/Source/LinqToDB.Templates/DataAnnotations.ttinclude +++ /dev/null @@ -1,65 +0,0 @@ -<# - { - var beforeGenerateModel = BeforeGenerateModel; - BeforeGenerateModel = () => - { - beforeGenerateModel(); - DataAnnotationsImpl(); - }; - } -#> -<#+ -void DataAnnotationsImpl() -{ - foreach (Class cl in GetTreeNodes(Model).OfType()) - { - foreach (var p in GetTreeNodes(cl).OfType()) - { - if (p.DisplayName != null) - { - p.Attributes.Add(new Attribute("Display", "Name=\"" + p.DisplayName + "\"") { IsSeparated = true }); - } - - if (p.IsRequired) - { - var attr = new Attribute("Required") { IsSeparated = true }; - - if (p.IsRequiredMessage != null) - attr.Parameters.Add(string.Format("ErrorMessage=\"" + p.IsRequiredMessage + "\"", p.DisplayName ?? p.Name)); - - p.Attributes.Add(attr); - } - - if (p.StringLength > 0) - { - var attr = new Attribute("StringLength", p.StringLength.ToString()) { IsSeparated = true }; - - if (p.StringLengthMessage != null) - attr.Parameters.Add(string.Format("ErrorMessage=\"" + p.StringLengthMessage + "\"", p.DisplayName ?? p.Name)); - - p.Attributes.Add(attr); - -// p.Attributes.Add( -// new Attribute("StringLength", -// p.StringLength.ToString(), -// string.Format( -// "ErrorMessage=\"The {0} must be a string with a maximum lenfth of {1}.\"", -// p.DisplayName ?? "field", -// p.StringLength)) -// { -// IsSeparated = true -// }); - } - } - } -} - -partial class Property -{ - public string DisplayName; - public bool IsRequired; - public string IsRequiredMessage; - public int StringLength; - public string StringLengthMessage; -} -#> diff --git a/Source/LinqToDB.Templates/DataModel.ttinclude b/Source/LinqToDB.Templates/DataModel.ttinclude deleted file mode 100644 index 95e6f52..0000000 --- a/Source/LinqToDB.Templates/DataModel.ttinclude +++ /dev/null @@ -1,862 +0,0 @@ -<#@ assembly name="System.Data" #> -<#@ import namespace="System.Data" #> -<#@ import namespace="LinqToDB.SchemaProvider" #> -<#@ import namespace="LinqToDB.Data" #> -<#@ include file="T4Model.ttinclude" #> -<# - { - var beforeGenerateModel = BeforeGenerateModel; - BeforeGenerateModel = () => - { - GenerateTypesFromMetadata(); - beforeGenerateModel(); - }; - } -#><#+ - -string NamespaceName -{ - get { return Model.Namespace.Name; } - set { Model.Namespace.Name = value; } -} - -string DatabaseName = null; -string DataContextName = null; -string BaseDataContextClass = null; -string BaseEntityClass = null; -string OneToManyAssociationType = "IEnumerable<{0}>"; - -bool GenerateDatabaseName = false; -bool GenerateConstructors = true; -string DefaultConfiguration = null; -bool GenerateAssociations = true; -bool GenerateBackReferences = true; -bool GenerateAssociationExtensions = false; -bool ReplaceSimilarTables = true; -bool IncludeDefaultSchema = true; - -Class DataContextObject; - -bool PluralizeClassNames = false; -bool SingularizeClassNames = true; -bool PluralizeDataContextPropertyNames = true; -bool SingularizeDataContextPropertyNames = false; - -bool NormalizeNames = true; - -private Func _toValidName; -Func ToValidName -{ - get { return _toValidName ?? ToValidNameDefault; } - set { _toValidName = value; } -} - -private Func _convertToCompilabl; -Func ConvertToCompilable -{ - get { return _convertToCompilabl ?? ConvertToCompilableDefault; } - set { _convertToCompilabl = value; } -} - -private Func _getAssociationExtensionPluralName; -Func GetAssociationExtensionPluralName -{ - get { return _getAssociationExtensionPluralName ?? GetAssociationExtensionPluralNameDefault; } - set { _getAssociationExtensionPluralName = value; } -} - -private Func _getAssociationExtensionSingularName; -Func GetAssociationExtensionSinglularName -{ - get { return _getAssociationExtensionSingularName ?? GetAssociationExtensionSinglularNameDefault; } - set { _getAssociationExtensionSingularName = value; } -} - -LinqToDB.SchemaProvider.GetSchemaOptions GetSchemaOptions = - new LinqToDB.SchemaProvider.GetSchemaOptions(); - -LinqToDB.SqlProvider.ISqlBuilder SqlBuilder; - -Func LoadProviderSpecificTable = tableSchema => null; - -static Func ConvertColumnMemberType = (c) => c.MemberType; -static Func ConvertTableColumnMemberType = (t,c) => ConvertColumnMemberType(c); -static Func ConvertProcedureColumnMemberType = (t,c) => ConvertColumnMemberType(c); - -HashSet KeyWords = new HashSet -{ - "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" -}; - -void LoadServerMetadata(DataConnection dataConnection) -{ - SqlBuilder = dataConnection.DataProvider.CreateSqlBuilder(); - - var sp = dataConnection.DataProvider.GetSchemaProvider(); - var db = sp.GetSchema(dataConnection, GetSchemaOptions); - - if (DatabaseName == null && GenerateDatabaseName) - DatabaseName = db.Database; - - if (DataContextName == null) - DataContextObject.Name = DataContextName = (ToValidName(db.Database, true) + "DB"); - - DataContextObject.Comment.Add("/ "); - DataContextObject.Comment.Add("/ Database : " + db.Database); - DataContextObject.Comment.Add("/ Data Source : " + db.DataSource); - DataContextObject.Comment.Add("/ Server Version : " + db.ServerVersion); - DataContextObject.Comment.Add("/ "); - - var tables = db.Tables - .Where(t => !t.IsProviderSpecific) - .Select(t => new - { - t, - key = t.IsDefaultSchema ? t.TableName : t.SchemaName + "." + t.TableName, - table = new Table - { - TableSchema = t, - Schema = (t.IsDefaultSchema && !IncludeDefaultSchema) || string.IsNullOrEmpty(t.SchemaName)? null : t.SchemaName, - BaseClass = BaseEntityClass, - TableName = t.TableName, - TypeName = t.TypeName, - DataContextPropertyName = t.TypeName, - IsView = t.IsView, - IsProviderSpecific = false, - Description = t.Description, - Columns = t.Columns.ToDictionary( - c => c.ColumnName, - c => new Column - { - ColumnName = c.ColumnName, - ColumnType = c.ColumnType, - DataType = "DataType." + c.DataType, - Length = c.Length, - Precision = c.Precision, - Scale = c.Scale, - IsNullable = c.IsNullable, - IsIdentity = c.IsIdentity, - IsPrimaryKey = c.IsPrimaryKey, - PrimaryKeyOrder = c.PrimaryKeyOrder, - MemberName = CheckType(c.SystemType, c.MemberName), - Type = ConvertTableColumnMemberType(t, c), - SkipOnInsert = c.SkipOnInsert, - SkipOnUpdate = c.SkipOnUpdate, - Description = c.Description, - }) - } - }) - .ToList(); - - if (PluralizeClassNames || SingularizeClassNames) - { - var foundNames = new HashSet(tables.Select(t => t.table.TypeName)); - foreach (var t in tables) - { - var newName = t.table.TypeName; - newName = - PluralizeClassNames ? ToPlural (newName) : - SingularizeClassNames ? ToSingular(newName) : newName; - - if (newName != t.table.TypeName) - { - if (!foundNames.Contains(newName)) - { - t.table.TypeName = newName; - foundNames.Add(newName); - } - } - } - } - - if (PluralizeDataContextPropertyNames || SingularizeDataContextPropertyNames) - { - var foundNames = new HashSet(tables.Select(t => t.table.DataContextPropertyName)); - foreach (var t in tables) - { - var newName = t.table.DataContextPropertyName; - newName = - PluralizeDataContextPropertyNames ? ToPlural (newName) : - SingularizeDataContextPropertyNames ? ToSingular(newName) : newName; - - if (newName != t.table.TypeName) - { - if (!foundNames.Contains(newName)) - { - t.table.DataContextPropertyName = newName; - foundNames.Add(newName); - } - } - } - } - - tables.AddRange(db.Tables - .Where(t => t.IsProviderSpecific) - .Select(t => new - { - t, - key = t.IsDefaultSchema ? t.TableName : t.SchemaName + "." + t.TableName, - table = LoadProviderSpecificTable(t) - }) - .Where(t => t.table != null)); - - foreach (var t in tables) - Tables.Add(t.key, t.table); - - var keys = - ( - from t in tables - from k in t.t.ForeignKeys - let otherTable = tables.Where(tbl => tbl.t == k.OtherTable).Select(tbl => tbl.table).Single() - select new - { - k, - k.KeyName, - t, - key = new ForeignKey - { - KeyName = k.KeyName, - OtherTable = otherTable, - OtherColumns = k.OtherColumns.Select(c => otherTable.Columns[c.ColumnName]).ToList(), - ThisColumns = k.ThisColumns. Select(c => t.table. Columns[c.ColumnName]).ToList(), - CanBeNull = k.CanBeNull, - MemberName = k.MemberName, - AssociationType = (AssociationType)(int)k.AssociationType, - } - } - ).ToList(); - - foreach (var key in keys) - { - var keyName = key.k.OtherTable.IsDefaultSchema ? key.KeyName : key.k.OtherTable.SchemaName + "." + key.KeyName; - ForeignKey foundKey; - if (key.t.table.ForeignKeys.TryGetValue(keyName, out foundKey)) - { - key.t.table.ForeignKeys.Remove(keyName); - key.t.table.ForeignKeys.Add(foundKey.OtherTable.TableName + "." + keyName, foundKey); - keyName = key.k.OtherTable.TableName + "." + keyName; - } - - key.t.table.ForeignKeys.Add( - key.k.OtherTable.IsDefaultSchema ? key.KeyName : key.k.OtherTable.SchemaName + "." + key.KeyName, - key.key); - - if (key.k.BackReference != null) - key.key.BackReference = keys.First(k => k.k == key.k.BackReference).key; - } - - var procedures = db.Procedures - .Select(p => new - { - p, - key = p.IsDefaultSchema ? p.ProcedureName : p.SchemaName + "." + p.ProcedureName, - proc = new Procedure - { - Schema = (p.IsDefaultSchema && !IncludeDefaultSchema) || string.IsNullOrEmpty(p.SchemaName)? null : p.SchemaName, - ProcedureName = p.ProcedureName, - Name = ToValidName(p.MemberName, true), - IsFunction = p.IsFunction, - IsTableFunction = p.IsTableFunction, - IsDefaultSchema = p.IsDefaultSchema, - IsLoaded = p.IsLoaded, - ResultTable = p.ResultTable == null ? null : - new Table - { - TypeName = ToValidName( - PluralizeClassNames ? ToPlural (p.ResultTable.TypeName) : - SingularizeClassNames ? ToSingular(p.ResultTable.TypeName) : p.ResultTable.TypeName, true), - Columns = ToDictionary( - p.ResultTable.Columns, - c => c.ColumnName, - c => new Column - { - ColumnName = c.ColumnName, - ColumnType = c.ColumnType, - IsNullable = c.IsNullable, - IsIdentity = c.IsIdentity, - IsPrimaryKey = c.IsPrimaryKey, - PrimaryKeyOrder = c.PrimaryKeyOrder, - MemberName = CheckColumnName(CheckType(c.SystemType, c.MemberName)), - Type = ConvertProcedureColumnMemberType(p, c), - SkipOnInsert = c.SkipOnInsert, - SkipOnUpdate = c.SkipOnUpdate, - Description = c.Description, - }, - (c,n) => - { - c.IsDuplicateOrEmpty = true; - return "$" + (c.MemberName = "Column" + n); - }) - }, - ResultException = p.ResultException, - SimilarTables = p.SimilarTables == null ? new List() : - p.SimilarTables - .Select(t => tables.Single(tbl => tbl.t == t).table) - .ToList(), - ProcParameters = p.Parameters - .Select(pr => new Parameter - { - SchemaName = pr.SchemaName, - SchemaType = pr.SchemaType, - IsIn = pr.IsIn, - IsOut = pr.IsOut, - IsResult = pr.IsResult, - Size = pr.Size, - ParameterName = CheckParameterName(pr.ParameterName), - ParameterType = pr.ParameterType, - SystemType = pr.SystemType, - DataType = pr.DataType.ToString(), - }) - .ToList(), - } - }) - .ToList(); - - foreach (var p in procedures) - { - if (ReplaceSimilarTables) - if (p.proc.SimilarTables.Count() == 1 || p.proc.SimilarTables.Count(t => !t.IsView) == 1) - p.proc.ResultTable = p.proc.SimilarTables.Count() == 1 ? - p.proc.SimilarTables[0] : - p.proc.SimilarTables.First(t => !t.IsView); - - Procedures[p.key] = p.proc; - } -} - -Dictionary ToDictionary(IEnumerable source, Func keyGetter, Func objGetter, Func getKeyName) -{ - var dic = new Dictionary(); - var current = 1; - - foreach (var item in source) - { - var key = keyGetter(item); - var obj = objGetter(item); - - if (string.IsNullOrEmpty(key) || dic.ContainsKey(key)) - key = getKeyName(obj, current); - - dic.Add(key, obj); - - current++; - } - - return dic; -} - -string CheckType(Type type, string typeName) -{ - if (!Model.Usings.Contains(type.Namespace)) - Model.Usings.Add(type.Namespace); - return typeName; -} - -string CheckColumnName(string memberName) -{ - if (string.IsNullOrEmpty(memberName)) - memberName = "Empty"; - else - { - memberName = memberName - .Replace("%", "Percent") - .Replace(">", "Greater") - .Replace("<", "Lower") - .Replace("+", "Plus") - .Replace('(', '_') - .Replace(')', '_') - .Replace('-', '_') - .Replace('|', '_') - .Replace(',', '_') - .Replace('"', '_') - .Replace("'", "_") - .Replace(".", "_") - .Replace("\u00A3", "Pound"); - - if (KeyWords.Contains(memberName)) - memberName = "@" + memberName; - } - return memberName; -} - -string CheckParameterName(string parameterName) -{ - var invalidParameterNames = new List - { - "@DataType" - }; - - var result = parameterName; - while (invalidParameterNames.Contains(result)) - { - result = result + "_"; - } - return result; -} - -Action AfterLoadMetadata = () => {}; - -void LoadMetadata(DataConnection dataConnection) -{ - if (DataContextObject == null) - { - DataContextObject = new Class(DataContextName) { BaseClass = BaseDataContextClass, }; - - Model.Types.Add(DataContextObject); - } - - LoadServerMetadata(dataConnection); - - if (Tables.Values.SelectMany(_ => _.ForeignKeys.Values).Any(_ => _.AssociationType == AssociationType.OneToMany)) - Model.Usings.Add("System.Collections.Generic"); - - foreach (var t in Tables.Values) - { - if (KeyWords.Contains(t.TypeName)) - t.TypeName = "@" + t.TypeName; - - if (KeyWords.Contains(t.DataContextPropertyName)) - t.DataContextPropertyName = "@" + t.DataContextPropertyName; - - t.TypeName = ConvertToCompilable(t.TypeName, true); - t.DataContextPropertyName = ConvertToCompilable(t.DataContextPropertyName, true); - - foreach (var col in t.Columns.Values) - { - if (KeyWords.Contains(col.MemberName)) - col.MemberName = "@" + col.MemberName; - - col.MemberName = ConvertToCompilable(col.MemberName, true); - - if (col.MemberName == t.TypeName) - col.MemberName += "_Column"; - } - } - - foreach (var t in Tables.Values) - { - foreach (var fk in t.ForeignKeys.Values) - { - var memberName = fk.OtherTable.TypeName; - - memberName = fk.AssociationType == AssociationType.OneToMany ? - ToPlural(memberName) : ToSingular(memberName); - - fk.MemberName = memberName; - } - } - - foreach (var t in Tables.Values) - { - var forbidden = KeyWords.Concat(new [] {t.TypeName}); - - var hasDuplicates = t.Columns.Values - .Select(c => c.MemberName) - .Concat(t.ForeignKeys.Values.Select(f => f.MemberName)) - .Concat(forbidden) - .ToLookup(n => n) - .Any(g => g.Count() > 1); - - if (hasDuplicates) - { - foreach (var fk in t.ForeignKeys.Values) - { - var mayDuplicate = t.Columns.Values - .Select(c => c.MemberName) - .Concat(forbidden) - .Concat(t.ForeignKeys.Values.Where(f => f != fk).Select(f => f.MemberName)); - - fk.MemberName = SuggestNoDuplicate(mayDuplicate, fk.MemberName, "FK"); - } - - foreach (var col in t.Columns.Values) - { - var mayDuplicate = t.Columns.Values - .Where(c => c != col) - .Select(c => c.MemberName) - .Concat(forbidden) - .Concat(t.ForeignKeys.Values.Select(fk => fk.MemberName)); - - col.MemberName = SuggestNoDuplicate(mayDuplicate, col.MemberName, null); - } - } - } - - AfterLoadMetadata(); -} - -string SuggestNoDuplicate(IEnumerable currentNames, string newName, string prefix) -{ - var names = new HashSet(currentNames); - var result = newName; - if (names.Contains(result)) - { - if (!string.IsNullOrEmpty(prefix)) - result = prefix + result; - if (names.Contains(result)) - { - var counter = 0; - var number = string.Concat(result.Reverse().Take(6).TakeWhile(c => Char.IsDigit(c)).Reverse()); - if (!string.IsNullOrEmpty(number)) - { - if (int.TryParse(number, out counter)) - { - result = result.Remove(result.Length - number.Length); - } - } - - do - { - ++counter; - if (!names.Contains(result + counter)) - { - result = result + counter; - break; - } - } - while(true); - } - } - - return result; -} - -string ConvertToCompilableDefault(string name, bool mayRemoveUnderscore) -{ - var query = - from c in name - select char.IsLetterOrDigit(c) || c == '@' ? c : '_'; - - return ToValidName(new string(query.ToArray()), mayRemoveUnderscore); -} - -Table GetTable(string name) -{ - Table tbl; - - if (Tables.TryGetValue(name, out tbl)) - return tbl; - - WriteLine("#error Table '" + name + "' not found."); - WriteLine("/*"); - WriteLine("\tExisting tables:"); - WriteLine(""); - - foreach (var key in Tables.Keys) - WriteLine("\t" + key); - - WriteLine(" */"); - - throw new ArgumentException("Table '" + name + "' not found."); -} - -Procedure GetProcedure(string name) -{ - Procedure proc; - - if (Procedures.TryGetValue(name, out proc)) - return proc; - - WriteLine("#error Procedure '" + name + "' not found."); - WriteLine(""); - WriteLine("/*"); - WriteLine("\tExisting procedures:"); - WriteLine(""); - - foreach (var key in Procedures.Keys) - WriteLine("\t" + key); - - WriteLine(" */"); - - throw new ArgumentException("Procedure '" + name + "' not found."); -} - -Column GetColumn(string tableName, string columnName) -{ - var tbl = GetTable(tableName); - - Column col; - - if (tbl.Columns.TryGetValue(columnName, out col)) - return col; - - WriteLine("#error Column '" + tableName + "'.'" + columnName + "' not found."); - WriteLine(""); - WriteLine("/*"); - WriteLine("\tExisting '" + tableName + "'columns:"); - WriteLine(""); - - foreach (var key in tbl.Columns.Keys) - WriteLine("\t" + key); - - WriteLine(" */"); - - throw new ArgumentException("Column '" + tableName + "'.'" + columnName + "' not found."); -} - -ForeignKey GetFK(string tableName, string fkName) -{ - return GetForeignKey(tableName, fkName); -} - -ForeignKey GetForeignKey(string tableName, string fkName) -{ - var tbl = GetTable(tableName); - - ForeignKey col; - - if (tbl.ForeignKeys.TryGetValue(fkName, out col)) - return col; - - WriteLine("#error FK '" + tableName + "'.'" + fkName + "' not found."); - WriteLine(""); - WriteLine("/*"); - WriteLine("\tExisting '" + tableName + "'FKs:"); - WriteLine(""); - - foreach (var key in tbl.ForeignKeys.Keys) - WriteLine("\t" + key); - - WriteLine(" */"); - - throw new ArgumentException("FK '" + tableName + "'.'" + fkName + "' not found."); -} - - -public TableContext SetTable(string tableName, - string TypeName = null, - string DataContextPropertyName = null) -{ - var ctx = new TableContext { Transformation = this, TableName = tableName }; - - if (TypeName != null || DataContextPropertyName != null) - { - var t = GetTable(tableName); - - if (TypeName != null) t.TypeName = TypeName; - if (DataContextPropertyName != null) t.DataContextPropertyName = DataContextPropertyName; - } - - return ctx; -} - -public class TableContext -{ - public GeneratedTextTransformation Transformation; - public string TableName; - - public TableContext Column(string columnName, - string MemberName = null, - string Type = null, - bool? IsNullable = null, - string Conditional = null) - { - var c = Transformation.GetColumn(TableName, columnName); - - if (MemberName != null) c.MemberName = MemberName; - if (Type != null) c.Type = Type; - if (IsNullable != null) c.IsNullable = IsNullable.Value; - if (Conditional != null) c.Conditional = Conditional; - - return this; - } - - public TableContext FK(string fkName, - string MemberName = null, - AssociationType? AssociationType = null, - bool? CanBeNull = null) - { - var c = Transformation.GetFK(TableName, fkName); - - if (MemberName != null) c.MemberName = MemberName; - if (AssociationType != null) c.AssociationType = AssociationType.Value; - if (CanBeNull != null) c.CanBeNull = CanBeNull.Value; - - return this; - } -} - - -Dictionary Tables = new Dictionary (); -Dictionary Procedures = new Dictionary(); - -public partial class Table : Class -{ - public TableSchema TableSchema { get; set; } - public string Schema { get; set; } - public string TableName { get; set; } - public string DataContextPropertyName { get; set; } - public MemberBase DataContextProperty { get; set; } - public bool IsView { get; set; } - public bool IsProviderSpecific { get; set; } - public string Description { get; set; } - public string AliasPropertyName { get; set; } - public string AliasTypeName { get; set; } - public string TypePrefix { get; set; } - - public string TypeName - { - get { return Name; } - set { Name = value; } - } - - public Dictionary Columns; - public Dictionary ForeignKeys = new Dictionary(); -} - -public partial class Column : Property -{ - public string ColumnName; // Column name in database - public bool IsNullable; - public bool IsIdentity; - public string ColumnType; // Type of the column in database - public string DataType; - public long? Length; - public int? Precision; - public int? Scale; - public DbType DbType; - public string Description; - public bool IsPrimaryKey; - public int PrimaryKeyOrder; - public bool SkipOnUpdate; - public bool SkipOnInsert; - public bool IsDuplicateOrEmpty; - public bool IsDiscriminator; - public string AliasName; - - public string MemberName - { - get { return Name; } - set { Name = value; } - } -} - -public enum AssociationType -{ - Auto, - OneToOne, - OneToMany, - ManyToOne, -} - -public partial class ForeignKey : Property -{ - public string KeyName; - public Table OtherTable; - public List ThisColumns; - public List OtherColumns; - public bool CanBeNull; - public ForeignKey BackReference; - - public string MemberName - { - get { return Name; } - set { Name = value; } - } - - private AssociationType _associationType = AssociationType.Auto; - public AssociationType AssociationType - { - get { return _associationType; } - set - { - _associationType = value; - - if (BackReference != null) - { - switch (value) - { - case AssociationType.Auto : BackReference.AssociationType = AssociationType.Auto; break; - case AssociationType.OneToOne : BackReference.AssociationType = AssociationType.OneToOne; break; - case AssociationType.OneToMany : BackReference.AssociationType = AssociationType.ManyToOne; break; - case AssociationType.ManyToOne : BackReference.AssociationType = AssociationType.OneToMany; break; - } - } - } - } -} - -public partial class Procedure : Method -{ - public string Schema { get; set; } - public string ProcedureName { get; set; } - public bool IsFunction { get; set; } - public bool IsTableFunction { get; set; } - public bool IsDefaultSchema { get; set; } - public bool IsLoaded { get; set; } - - public Table ResultTable { get; set; } - public Exception ResultException { get; set; } - public List
SimilarTables { get; set; } - public List ProcParameters { get; set; } -} - -public class Parameter -{ - public string SchemaName { get; set; } - public string SchemaType { get; set; } - public bool IsIn { get; set; } - public bool IsOut { get; set; } - public bool IsResult { get; set; } - public long? Size { get; set; } - - public string ParameterName { get; set; } - public string ParameterType { get; set; } - public Type SystemType { get; set; } - public string DataType { get; set; } -} - -private int _counter = 0; - -string ToValidNameDefault(string name, bool mayRemoveUnderscore) -{ - if (NormalizeNames && mayRemoveUnderscore && name.Contains("_")) - { - name = SplitAndJoin(name, "", '_'); - } - - if (name.Contains(".")) - { - name = SplitAndJoin(name, "", '.'); - } - - if (name.Length > 0 && char.IsDigit(name[0])) - name = "_" + name; - - if (string.IsNullOrEmpty(name)) - name = "_" + _counter++; - - if (NormalizeNames) - { - name = char.ToUpper(name[0]) + name.Substring(1); - } - - return name; -} - -static string SplitAndJoin(string value, string join, params char[] split) -{ - var ss = value.Split(split, StringSplitOptions.RemoveEmptyEntries) - .Select(s => char.ToUpper(s[0]) + s.Substring(1)); - - return string.Join(join, ss.ToArray()); -} - -private string GetAssociationExtensionSinglularNameDefault(ForeignKey key) -{ - return ToSingular(key.Name); -} - -private string GetAssociationExtensionPluralNameDefault(ForeignKey key) -{ - return ToPlural(ToSingular(key.Name)); -} - -#> diff --git a/Source/LinqToDB.Templates/EditableObject.ttinclude b/Source/LinqToDB.Templates/EditableObject.ttinclude deleted file mode 100644 index dd4e4f2..0000000 --- a/Source/LinqToDB.Templates/EditableObject.ttinclude +++ /dev/null @@ -1,235 +0,0 @@ -<# - { - var beforeGenerateModel = BeforeGenerateModel; - BeforeGenerateModel = () => - { - EditableObjectImpl(); - beforeGenerateModel(); - }; - - SetPropertyValueAction += (obj,prop,val) => - { - if (prop == "IsEditable") - obj.IsEditable = (bool)val; - }; - } -#> -<#+ -void EditableObjectImpl() -{ - foreach (Property prop in GetTreeNodes(Model).OfType().Where(p => p.IsEditable).ToList()) - { - SetPropertyValue(prop, "IsNotifying", true); - - List parentMembers; - - MemberGroup gr = null; - - if (prop.Parent is Class) - { - var parent = (Class)prop.Parent; - parentMembers = parent.Members; - } - else - { - var parent = (MemberGroup)prop.Parent; - parentMembers = parent.Members; - - parent.IsCompact = false; - } - - var name = prop.Name.Trim(); - var type = prop.Type.Trim(); - - if (gr == null) - { - gr = new MemberGroup - { - Region = name + " : " + type, - Members = { prop }, - IsPropertyGroup = true, - }; - - var index = parentMembers.IndexOf(prop); - - parentMembers.RemoveAt(index); - parentMembers.Insert (index, gr); - } - - var originalField = new Field(type, "_original" + name) - { - AccessModifier = AccessModifier.Private, - InsertBlankLineAfter = false, - }; - - gr.Members.Insert(0, originalField); - - var currentField = new Field(type, " _current" + name) - { - AccessModifier = AccessModifier.Private, - InsertBlankLineAfter = false, - }; - - if (prop.InitValue != null) - currentField.InitValue = prop.InitValue; - - gr.Members.Insert(0, currentField); - - prop.Name = " " + name; - prop.Type = " " + type; - prop.IsAuto = false; - - if (prop.HasGetter) prop.GetBody.Add("return " + currentField.Name.Trim() + ";"); - if (prop.HasSetter) prop.SetBody.Add(currentField.Name.Trim() + " = value;"); - - var ac = new Method ("void", "Accept" + name + "Changes", null, new[] { string.Format("_original{0} = _current{0};", name) }); - var rc = new Method ("void", "Reject" + name + "Changes", null, new[] { string.Format("{0} = _original{0};", name) }); - var id = new Property("bool", "Is" + name + "Dirty") - .InitGetter(string.Format(prop.IsDirtyText, "_current" + name, "_original" + name)); - - gr.Members.Add(new MemberGroup - { - Region = "EditableObject support", - Members = { ac, rc, id }, - }); - - prop.Parent.SetTree(); - } - - foreach (Class cl in GetTreeNodes(Model).OfType()) - { - var props = GetTreeNodes(cl).OfType().Where(p => p.IsEditable).ToList(); - - if (props.Count > 0) - { - if (props.Any(p => p.IsEditable)) - { - var ctor = GetTreeNodes(cl) - .OfType() - .FirstOrDefault(m => m.Name == cl.Name && m.Parameters.Count == 0); - - if (ctor == null) - { - ctor = new Method(null, cl.Name); - cl.Members.Insert(0, ctor); - } - - ctor.Body.Add("AcceptChanges();"); - } - - var maxLen = props.Max(p => p.Name.Trim().Length); - - var ac = new Method("void", "AcceptChanges") { IsVirtual = true }; - var rc = new Method("void", "RejectChanges") { IsVirtual = true }; - var id = new Property("bool", "IsDirty") { IsAuto = false, HasSetter = false, IsVirtual = true }; - - ac.Body.Add("BeforeAcceptChanges();"); - ac.Body.Add(""); - rc.Body.Add("BeforeRejectChanges();"); - rc.Body.Add(""); - id.GetBody.Add("return"); - - foreach (var p in props) - { - var name = p.Name.Trim(); - - ac.Body.Add(string.Format("Accept{0}Changes();", name)); - rc.Body.Add(string.Format("Reject{0}Changes();", name)); - id.GetBody.Add(string.Format("\tIs{0}Dirty{1} ||", name, LenDiff(maxLen, name))); - } - - ac.Body.Add(""); - ac.Body.Add("AfterAcceptChanges();"); - rc.Body.Add(""); - rc.Body.Add("AfterRejectChanges();"); - id.GetBody[id.GetBody.Count - 1] = id.GetBody[id.GetBody.Count - 1].Trim(' ' , '|') + ";"; - - cl.Members.Add(new MemberGroup - { - Region = "EditableObject support", - Members = - { - new MemberGroup - { - IsCompact = true, - Members = - { - new Method("void", "BeforeAcceptChanges") { AccessModifier = AccessModifier.Partial }, - new Method("void", "AfterAcceptChanges") { AccessModifier = AccessModifier.Partial }, - } - }, - ac, - new MemberGroup - { - IsCompact = true, - Members = - { - new Method("void", "BeforeRejectChanges") { AccessModifier = AccessModifier.Partial }, - new Method("void", "AfterRejectChanges") { AccessModifier = AccessModifier.Partial }, - } - }, - rc, - id - }, - }); - - if (!cl.Interfaces.Contains("IEditableObject")) - { - if (!Model.Usings.Contains("System.ComponentModel")) - Model.Usings.Add("System.ComponentModel"); - - cl.Interfaces.Add("IEditableObject"); - - cl.Members.Add(new MemberGroup - { - Region = "IEditableObject support", - Members = - { - new MemberGroup - { - IsCompact = true, - Members = - { - new Field ("bool", "_isEditing") { AccessModifier = AccessModifier.Private }, - new Property("bool", " IsEditing").InitGetter("_isEditing"), - } - }, - new MemberGroup - { - IsCompact = true, - Members = - { - new Method("void", "BeginEdit", null, new[] { "AcceptChanges();", "_isEditing = true;" }) { IsVirtual = true }, - new Method("void", "CancelEdit", null, new[] { "_isEditing = false;", "RejectChanges();", }) { IsVirtual = true }, - new Method("void", "EndEdit", null, new[] { "_isEditing = false;", "AcceptChanges();", }) { IsVirtual = true }, - } - }, - } - }); - } - } - - cl.SetTree(); - } -} - -partial class Property -{ - public bool IsEditable; - public string IsDirtyText = "{0} != {1}"; -} - -class EditableProperty : Property -{ - public EditableProperty() - { - IsEditable = true; - } - - public EditableProperty(string type, string name) - : base(type, name, null, null) - { - IsEditable = true; - } -} -#> diff --git a/Source/LinqToDB.Templates/Humanizer.ttinclude b/Source/LinqToDB.Templates/Humanizer.ttinclude deleted file mode 100644 index 88f657b..0000000 --- a/Source/LinqToDB.Templates/Humanizer.ttinclude +++ /dev/null @@ -1,18 +0,0 @@ -<# -/* -To use this extension tou should: -1) Reference Humanizer NuGet package into your project -2) Iclude Humanizer.ttinclude -3) Reference assembly like aassembly name="$(SolutionDir)\packages\Humanizer.Core.2.2.0\lib\netstandard1.0\Humanizer.dll" -*/ - -#> -<#@ import namespace="Humanizer" #> -<# - { - ToPlural = s => s.Pluralize (inputIsKnownToBeSingular: false); - ToSingular = s => s.Singularize(inputIsKnownToBePlural: false); - ToValidName = (s, r) => s.Pascalize(); - - } -#> \ No newline at end of file diff --git a/Source/LinqToDB.Templates/LinqToDB.Access.ttinclude b/Source/LinqToDB.Templates/LinqToDB.Access.ttinclude deleted file mode 100644 index 4d36a2c..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.Access.ttinclude +++ /dev/null @@ -1,26 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<#+ -LinqToDB.Data.DataConnection GetAccessConnection(string connectionString) -{ - return LinqToDB.DataProvider.Access.AccessTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetAccessConnection(string path, string database) -{ - return GetAccessConnection(string.Format( - "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Locale Identifier=1033;Jet OLEDB:Engine Type=5;Persist Security Info=True", - System.IO.Path.Combine(path, database))); -} - -void LoadAccessMetadata(string connectionString) -{ - var dataConnection = GetAccessConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadAccessMetadata(string path, string database) -{ - var dataConnection = GetAccessConnection(path, database); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.DB2.ttinclude b/Source/LinqToDB.Templates/LinqToDB.DB2.ttinclude deleted file mode 100644 index 466ca8f..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.DB2.ttinclude +++ /dev/null @@ -1,28 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.DB2.DB2Tools.ResolveDB2( - typeof(IBM.Data.DB2.DB2Connection).Assembly); -#><#+ -LinqToDB.Data.DataConnection GetDB2Connection(string connectionString) -{ - var conn = new IBM.Data.DB2.DB2Connection(connectionString); - return LinqToDB.DataProvider.DB2.DB2Tools.CreateDataConnection(conn); -} - -LinqToDB.Data.DataConnection GetDB2Connection(string server, string port, string database, string uid, string password) -{ - return GetDB2Connection(string.Format("Server={0}:{1};Database={2};UID={3};PWD={4};", server, port, database, uid, password)); -} - -void LoadDB2Metadata(string connectionString) -{ - var dataConnection = GetDB2Connection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadDB2Metadata(string server, string port, string database, string uid, string password) -{ - var dataConnection = GetDB2Connection(server, port, database, uid, password); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.Firebird.ttinclude b/Source/LinqToDB.Templates/LinqToDB.Firebird.ttinclude deleted file mode 100644 index 156a47f..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.Firebird.ttinclude +++ /dev/null @@ -1,71 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.Firebird.FirebirdTools.ResolveFirebird( - typeof(FirebirdSql.Data.FirebirdClient.FbConnection).Assembly); - - { - var afterLoadMetadata = AfterLoadMetadata; - AfterLoadMetadata = () => - { - afterLoadMetadata(); - CheckNameCasing(); - }; - } -#> -<#+ -void CheckNameCasing() -{ - foreach (var t in Tables.Values) - { - var name = t.TableName; - - if (!name.StartsWith("\"")) - if (name.StartsWith("_") || name.Any(c => char.IsLower(c) || char.IsWhiteSpace(c))) - t.TableName = "\\\"" + name + "\\\""; - - foreach (var col in t.Columns.Values) - { - name = col.ColumnName; - - if (!name.StartsWith("\"")) - if (name.StartsWith("_") || name.Any(c => char.IsLower(c) || char.IsWhiteSpace(c))) - col.ColumnName = "\\\"" + name + "\\\""; - } - } -} - -LinqToDB.Data.DataConnection GetFirebirdConnection(string connectionString) -{ - return LinqToDB.DataProvider.Firebird.FirebirdTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetFirebirdConnection(string server, string database) -{ - return GetFirebirdConnection(server, database, "SYSDBA", "masterkey"); -} - -LinqToDB.Data.DataConnection GetFirebirdConnection(string server, string database, string uid, string password) -{ - return GetFirebirdConnection(string.Format( - "DataSource={0};Database={1};User Id={2};Password={3}", - server, database, uid, password)); -} - -void LoadFirebirdMetadata(string connectionString) -{ - var dataConnection = GetFirebirdConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadFirebirdMetadata(string server, string database, string uid, string password) -{ - var dataConnection = GetFirebirdConnection(server, database, uid, password); - LoadMetadata(dataConnection); -} - -void LoadFirebirdMetadata(string server, string database) -{ - var dataConnection = GetFirebirdConnection(server, database); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.Informix.ttinclude b/Source/LinqToDB.Templates/LinqToDB.Informix.ttinclude deleted file mode 100644 index 0e6cc90..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.Informix.ttinclude +++ /dev/null @@ -1,28 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.Informix.InformixTools.ResolveInformix( - typeof(IBM.Data.Informix.IfxConnection).Assembly); -#><#+ -LinqToDB.Data.DataConnection GetInformixConnection(string connectionString) -{ - var conn = new IBM.Data.Informix.IfxConnection(connectionString); - return LinqToDB.DataProvider.Informix.InformixTools.CreateDataConnection(conn); -} - -LinqToDB.Data.DataConnection GetInformixConnection(string host, string port, string server, string database, string uid, string password) -{ - return GetInformixConnection(string.Format("Host={0};Service={1};Server={2};Protocol=onsoctcp;Database={3};UID={4};PWD={5}", host, port, server, database, uid, password)); -} - -void LoadInformixMetadata(string connectionString) -{ - var dataConnection = GetInformixConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadInformixMetadata(string host, string port, string server, string database, string uid, string password) -{ - var dataConnection = GetInformixConnection(host, port, server, database, uid, password); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.MySql.ttinclude b/Source/LinqToDB.Templates/LinqToDB.MySql.ttinclude deleted file mode 100644 index 3d96937..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.MySql.ttinclude +++ /dev/null @@ -1,30 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.MySql.MySqlTools.ResolveMySql( - typeof(MySql.Data.MySqlClient.MySqlConnection).Assembly); -#> -<#+ -LinqToDB.Data.DataConnection GetMySqlConnection(string connectionString) -{ - return LinqToDB.DataProvider.MySql.MySqlTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetMySqlConnection(string server, string database, string uid, string password, int port=3306) -{ - return GetMySqlConnection(string.Format( - "Server={0};Port={4};Database={1};Uid={2};Pwd={3};charset=utf8;", - server, database, uid, password,port)); -} - -void LoadMySqlMetadata(string connectionString) -{ - var dataConnection = GetMySqlConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadMySqlMetadata(string server, string database, string uid, string password,int port=3306) -{ - var dataConnection = GetMySqlConnection(server, database, uid, password,port); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.Oracle.ttinclude b/Source/LinqToDB.Templates/LinqToDB.Oracle.ttinclude deleted file mode 100644 index dabdefa..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.Oracle.ttinclude +++ /dev/null @@ -1,29 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.Oracle.OracleTools.AssemblyName = "Oracle.ManagedDataAccess"; - LinqToDB.DataProvider.Oracle.OracleTools.ResolveOracle( - typeof(Oracle.ManagedDataAccess.Client.OracleConnection).Assembly); -#><#+ -LinqToDB.Data.DataConnection GetOracleConnection(string connectionString) -{ - //return LinqToDB.DataProvider.Oracle.OracleTools.CreateDataConnection(connectionString); - return new LinqToDB.Data.DataConnection(new LinqToDB.DataProvider.Oracle.OracleDataProvider("OracleManaged"), connectionString); -} - -LinqToDB.Data.DataConnection GetOracleConnection(string server, string port, string database, string uid, string password) -{ - return GetOracleConnection(string.Format("Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={0})(PORT={1}))(CONNECT_DATA=(SERVICE_NAME={2})));User Id={3};Password={4};", server, port, database, uid, password)); -} - -void LoadOracleMetadata(string connectionString) -{ - var dataConnection = GetOracleConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadOracleMetadata(string server, string port, string database, string uid, string password) -{ - var dataConnection = GetOracleConnection(server, port, database, uid, password); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude b/Source/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude deleted file mode 100644 index 2ac6c38..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude +++ /dev/null @@ -1,57 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.PostgreSQL.PostgreSQLTools.ResolvePostgreSQL( - typeof(Npgsql.NpgsqlConnection).Assembly); - - { - var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; - BeforeGenerateLinqToDBModel = () => - { - beforeGenerateLinqToDBModel(); - SetCaseSensitiveNames(); - }; - } -#> -<#+ -bool GenerateCaseSensitiveNames = false; // Defines whether to generate case sensitive or insensitive names - -void SetCaseSensitiveNames() -{ - if (GenerateCaseSensitiveNames) - { - foreach (var t in Tables.Values) - { - if (t.TableName.Any(char.IsUpper)) - t.TableName = "\\\"" + t.TableName + "\\\""; - - foreach (var c in t.Columns.Values) - { - if (c.ColumnName.Any(char.IsUpper)) - c.ColumnName = "\\\"" + c.ColumnName + "\\\""; - } - } - } -} - -LinqToDB.Data.DataConnection GetPostgreSQLConnection(string connectionString) -{ - return LinqToDB.DataProvider.PostgreSQL.PostgreSQLTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetPostgreSQLConnection(string server, string port, string database, string uid, string password) -{ - return GetPostgreSQLConnection(string.Format(@"Server={0};Port={1};Database={2};User Id={3};Password={4};Pooling=true;MinPoolSize=10;MaxPoolSize=100;", server, port, database, uid, password)); -} - -void LoadPostgreSQLMetadata(string connectionString) -{ - var dataConnection = GetPostgreSQLConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadPostgreSQLMetadata(string server, string port, string database, string uid, string password) -{ - var dataConnection = GetPostgreSQLConnection(server, port, database, uid, password); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.SQLite.ttinclude b/Source/LinqToDB.Templates/LinqToDB.SQLite.ttinclude deleted file mode 100644 index 6b04b24..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.SQLite.ttinclude +++ /dev/null @@ -1,44 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.SQLite.SQLiteTools.ResolveSQLite(typeof(System.Data.SQLite.SQLiteConnection).Assembly); - - { - var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; - BeforeGenerateLinqToDBModel = () => - { - ConvertSQLiteMetadata(); - beforeGenerateLinqToDBModel(); - }; - } -#> -<#+ -void ConvertSQLiteMetadata() -{ - foreach (var t in Tables.Values) - foreach (var fk in t.ForeignKeys.Values) - if (fk.MemberName.Length == 0 || char.IsDigit(fk.MemberName[0])) - fk.MemberName = "FK_" + fk.MemberName; -} - -LinqToDB.Data.DataConnection GetSQLiteConnection(string connectionString) -{ - return LinqToDB.DataProvider.SQLite.SQLiteTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetSQLiteConnection(string path, string database) -{ - return GetSQLiteConnection(string.Format("Data Source={0}", System.IO.Path.Combine(path, database))); -} - -void LoadSQLiteMetadata(string connectionString) -{ - var dataConnection = GetSQLiteConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadSQLiteMetadata(string path, string database) -{ - var dataConnection = GetSQLiteConnection(path, database); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.SapHana.ttinclude b/Source/LinqToDB.Templates/LinqToDB.SapHana.ttinclude deleted file mode 100644 index 0cbb3e8..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.SapHana.ttinclude +++ /dev/null @@ -1,109 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<#@ import namespace="LinqToDB.DataProvider.SapHana" #> -<# - LinqToDB.DataProvider.SapHana.SapHanaTools.ResolveSapHana( - typeof(Sap.Data.Hana.HanaConnection).Assembly); - - Model.Usings.Add("LinqToDB.DataProvider.SapHana"); - Model.Usings.Add("System.Reflection"); - - GenerateProviderSpecificTable = t => - { - var method = new Method( - String.Format("ITable<{0}>", t.TypeName), - t.DataContextPropertyName, - t.Parameters.Select(p => p.ParameterType + " " + p.ParameterName), - new [] - { - String.Concat("return GetTable<",t.TypeName,">(this, (MethodInfo) MethodBase.GetCurrentMethod(),"), - String.Join(",", t.Parameters.Select(p => p.ParameterName)), - ");" - }); - - method.Attributes.Add(new Attribute("CalculationViewInputParametersExpression", new string[] {})); - return method; - }; - - LoadProviderSpecificTable = t => - { - var v = t as ViewWithParametersTableSchema; - return new Table - { - Schema = (t.IsDefaultSchema && !IncludeDefaultSchema) || string.IsNullOrEmpty(t.SchemaName)? null : t.SchemaName, - BaseClass = BaseEntityClass, - TableName = t.TableName, - TypeName = - PluralizeClassNames ? ToPlural (t.TypeName) : - SingularizeClassNames ? ToSingular(t.TypeName) : t.TypeName, - DataContextPropertyName = - PluralizeDataContextPropertyNames ? ToPlural (t.TypeName) : - SingularizeDataContextPropertyNames ? ToSingular(t.TypeName) : t.TypeName, - IsView = t.IsView, - IsProviderSpecific = true, - Description = t.Description, - Columns = t.Columns.ToDictionary( - c => c.ColumnName, - c => new Column - { - ColumnName = c.ColumnName, - ColumnType = c.ColumnType, - IsNullable = c.IsNullable, - IsIdentity = c.IsIdentity, - IsPrimaryKey = c.IsPrimaryKey, - PrimaryKeyOrder = c.PrimaryKeyOrder, - MemberName = CheckType(c.SystemType, c.MemberName), - Type = c.MemberType, - SkipOnInsert = c.SkipOnInsert, - SkipOnUpdate = c.SkipOnUpdate, - Description = c.Description, - }), - Parameters = v.Parameters.Select(pr => new Parameter - { - SchemaName = pr.SchemaName, - SchemaType = pr.SchemaType, - IsIn = pr.IsIn, - IsOut = pr.IsOut, - IsResult = pr.IsResult, - Size = pr.Size, - ParameterName = pr.ParameterName, - ParameterType = pr.ParameterType, - SystemType = pr.SystemType, - DataType = pr.DataType.ToString(), - }) - .ToList() - }; - }; -#> -<#+ - public partial class Table - { - public List Parameters; - } - - LinqToDB.Data.DataConnection GetSapHanaConnection(string connectionString) - { - return LinqToDB.DataProvider.SapHana.SapHanaTools.CreateDataConnection(connectionString); - } - - LinqToDB.Data.DataConnection GetSapHanaConnection(string server, string schema, string uid, string password) - { - return GetSapHanaConnection(string.Format("Server={0};Current Schema={1};UserID={2};Password={3};", server, schema, uid, password)); - } - - void LoadSapHanaMetadata(DataConnection dataConnection) - { - LoadMetadata(dataConnection); - } - - void LoadSapHanaMetadata(string connectionString) - { - var dataConnection = GetSapHanaConnection(connectionString); - LoadMetadata(dataConnection); - } - - void LoadSapHanaMetadata(string server, string schema, string uid, string password) - { - var dataConnection = GetSapHanaConnection(server, schema, uid, password); - LoadMetadata(dataConnection); - } -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude b/Source/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude deleted file mode 100644 index 4160979..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude +++ /dev/null @@ -1,28 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.SqlCe.SqlCeTools.ResolveSqlCe( - typeof(System.Data.SqlServerCe.SqlCeConnection).Assembly); -#> -<#+ -LinqToDB.Data.DataConnection GetSqlCeConnection(string connectionString) -{ - return LinqToDB.DataProvider.SqlCe.SqlCeTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetSqlCeConnection(string path, string database) -{ - return GetSqlCeConnection(string.Format("Data Source={0}", System.IO.Path.Combine(path, database))); -} - -void LoadSqlCeMetadata(string connectionString) -{ - var dataConnection = GetSqlCeConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadSqlCeMetadata(string path, string database) -{ - var dataConnection = GetSqlCeConnection(path, database); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude b/Source/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude deleted file mode 100644 index aded8bd..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude +++ /dev/null @@ -1,5 +0,0 @@ -<#@ include file="LinqToDB.SqlServer.ttinclude" #> -<# - LinqToDB.DataProvider.SqlServer.SqlServerTools.ResolveSqlTypes( - typeof(Microsoft.SqlServer.Types.SqlGeography).Assembly); -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude b/Source/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude deleted file mode 100644 index 74791db..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude +++ /dev/null @@ -1,130 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - { - var afterGenerateLinqToDBModel = AfterGenerateLinqToDBModel; - AfterGenerateLinqToDBModel = () => - { - afterGenerateLinqToDBModel(); - DoGenerateSqlServerFreeText(); - }; - } -#> -<#+ -bool GenerateSqlServerFreeText = true; // Defines whether to generate extensions for Free Text search, or not - -void DoGenerateSqlServerFreeText() -{ - if (!GenerateSqlServerFreeText) - return; - - Model.Usings.Add("System.Collections.Generic"); - Model.Usings.Add("System.Linq.Expressions"); - Model.Usings.Add("System.Reflection"); - Model.Usings.Add("LinqToDB"); - Model.Usings.Add("LinqToDB.DataProvider.SqlServer"); - Model.Usings.Add("LinqToDB.Extensions"); - - DataContextObject.Members.Add( - new MemberGroup - { - Region = "FreeTextTable", - Members = - { - new Class("FreeTextKey", - new MemberGroup - { - IsCompact = true, - Members = - { - new Field("T", "Key"), - new Field("int", "Rank") - } - }) - { - IsPartial = false - }, - - new Field("MethodInfo", "_freeTextTableMethod1") - { - AccessModifier = AccessModifier.Private, - IsStatic = true, - InitValue = "typeof(" + DataContextObject.Name + ").GetMethod(\"FreeTextTable\", new Type[] { typeof(string), typeof(string) })" - }, - - new Method("ITable>", "FreeTextTable", - new[] { "string field", "string text" }, - new[] - { - "return this.GetTable>(", - " this,", - " _freeTextTableMethod1,", - " field,", - " text);", - }) - { - Attributes = { new Attribute("FreeTextTableExpression") } - }, - - new Field("MethodInfo", "_freeTextTableMethod2") - { - AccessModifier = AccessModifier.Private, - IsStatic = true, - InitValue = Environment.NewLine + - " typeof(" + DataContextObject.Name + ").GetMethods()" + Environment.NewLine + - " .Where(m => m.Name == \"FreeTextTable\" && m.IsGenericMethod && m.GetParameters().Length == 2)" + Environment.NewLine + - " .Where(m => m.GetParameters()[0].ParameterType.IsGenericTypeEx() && m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(Expression<>))" + Environment.NewLine + - " .Where(m => m.GetParameters()[1].ParameterType == typeof(string))" + Environment.NewLine + - " .Single()" - }, - - new Method("ITable>", "FreeTextTable", - new[] { "Expression> fieldSelector", "string text" }, - new[] - { - "return this.GetTable>(", - " this,", - " _freeTextTableMethod2,", - " fieldSelector,", - " text);", - }) - { - Attributes = { new Attribute("FreeTextTableExpression") } - }, - } - } - ); -} - -LinqToDB.Data.DataConnection GetSqlServerConnection(string connectionString) -{ - return LinqToDB.DataProvider.SqlServer.SqlServerTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetSqlServerConnection(string server, string database) -{ - return GetSqlServerConnection(string.Format("Data Source={0};Database={1};Integrated Security=SSPI", server, database)); -} - -LinqToDB.Data.DataConnection GetSqlServerConnection(string server, string database, string user, string password) -{ - return GetSqlServerConnection(string.Format("Server={0};Database={1};User Id={2};Password={3};", server, database, user, password)); -} - -void LoadSqlServerMetadata(string connectionString) -{ - var dataConnection = GetSqlServerConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadSqlServerMetadata(string server, string database) -{ - var dataConnection = GetSqlServerConnection(server, database); - LoadMetadata(dataConnection); -} - -void LoadSqlServerMetadata(string server, string database, string user, string password) -{ - var dataConnection = GetSqlServerConnection(server, database, user, password); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.Sybase.ttinclude b/Source/LinqToDB.Templates/LinqToDB.Sybase.ttinclude deleted file mode 100644 index 154c181..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.Sybase.ttinclude +++ /dev/null @@ -1,82 +0,0 @@ -<#@ include file="LinqToDB.ttinclude" #> -<# - LinqToDB.DataProvider.Sybase.SybaseTools.ResolveSybase( - typeof(Sybase.Data.AseClient.AseConnection).Assembly); - - { - var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; - BeforeGenerateLinqToDBModel = () => - { - beforeGenerateLinqToDBModel(); - GenerateSybaseTypes(); - }; - } -#><#+ -bool GenerateSybaseSystemTables = false; // Defines whether to generate Sybase sysobjects tables or not - -void GenerateSybaseTypes() -{ - if (GenerateSybaseSystemTables) - { - Tables.Add("sysobjects", new Table - { - Name = "sysobjects", - TableName = "sysobjects", - TypeName = "SysObject", - DataContextPropertyName = "SysObjects", - BaseClass = BaseEntityClass, - Columns = new Dictionary() - { - { "name", new Column { Name = "name", ColumnName = "name", ColumnType = "varchar", Type = "string", DbType = DbType.AnsiString, /*Length = 255*/ }}, - { "id", new Column { Name = "id", ColumnName = "id", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "uid", new Column { Name = "uid", ColumnName = "uid", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "type", new Column { Name = "type", ColumnName = "type", ColumnType = "char", Type = "string", DbType = DbType.AnsiStringFixedLength, /*Length = 2,*/ }}, - { "userstat", new Column { Name = "userstat", ColumnName = "userstat", ColumnType = "smallint", Type = "short", DbType = DbType.Int16, }}, - { "sysstat", new Column { Name = "sysstat", ColumnName = "sysstat", ColumnType = "smallint", Type = "short", DbType = DbType.Int16, }}, - { "indexdel", new Column { Name = "indexdel", ColumnName = "indexdel", ColumnType = "smallint", Type = "short", DbType = DbType.Int16, }}, - { "schemacnt", new Column { Name = "schemacnt", ColumnName = "schemacnt", ColumnType = "smallint", Type = "short", DbType = DbType.Int16, }}, - { "sysstat2", new Column { Name = "sysstat2", ColumnName = "sysstat2", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "crdate", new Column { Name = "crdate", ColumnName = "crdate", ColumnType = "datetime", Type = "DateTime", DbType = DbType.DateTime }}, - { "expdate", new Column { Name = "expdate", ColumnName = "expdate", ColumnType = "datetime", Type = "DateTime", DbType = DbType.DateTime }}, - { "deltrig", new Column { Name = "deltrig", ColumnName = "deltrig", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "instrig", new Column { Name = "instrig", ColumnName = "instrig", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "updtrig", new Column { Name = "updtrig", ColumnName = "updtrig", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "seltrig", new Column { Name = "seltrig", ColumnName = "seltrig", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "ckfirst", new Column { Name = "ckfirst", ColumnName = "ckfirst", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "cache", new Column { Name = "cache", ColumnName = "cache", ColumnType = "smallint", Type = "short", DbType = DbType.Int16 }}, - { "audflags", new Column { Name = "audflags", ColumnName = "audflags", ColumnType = "int", Type = "int", DbType = DbType.Int32, IsNullable = true }}, - { "objspare", new Column { Name = "objspare", ColumnName = "objspare", ColumnType = "int", Type = "int", DbType = DbType.Int32, }}, - { "versionts", new Column { Name = "versionts", ColumnName = "versionts", ColumnType = "binary", Type = "byte[]", DbType = DbType.Binary, IsNullable = true, /*Length = 6*/ }}, - { "loginame", new Column { Name = "loginame", ColumnName = "loginame", ColumnType = "varchar", Type = "string", DbType = DbType.AnsiString, /*Length = 30*/ }}, - } - }); - } -} - -LinqToDB.Data.DataConnection GetSybaseConnection(string connectionString) -{ - return LinqToDB.DataProvider.Sybase.SybaseTools.CreateDataConnection(connectionString); -} - -LinqToDB.Data.DataConnection GetSybaseConnection(string server, string database) -{ - return GetSybaseConnection(string.Format("Data Source={0};Database={1};Integrated Security=SSPI", server, database)); -} - -LinqToDB.Data.DataConnection GetSybaseConnection(string server, string port, string database, string uid, string password) -{ - return GetSybaseConnection(string.Format("Data Source={0};Port={1};Database={2};Uid={3};Password={4};Charset=utf8;", server, port, database, uid, password)); -} - -void LoadSybaseMetadata(string connectionString) -{ - var dataConnection = GetSybaseConnection(connectionString); - LoadMetadata(dataConnection); -} - -void LoadSybaseMetadata(string server, string port, string database, string uid, string password) -{ - var dataConnection = GetSybaseConnection(server, port, database, uid, password); - LoadMetadata(dataConnection); -} -#> diff --git a/Source/LinqToDB.Templates/LinqToDB.Tools.ttinclude b/Source/LinqToDB.Templates/LinqToDB.Tools.ttinclude deleted file mode 100644 index 44d4529..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.Tools.ttinclude +++ /dev/null @@ -1 +0,0 @@ -<#@ assembly name="$(SolutionDir).tools\linq2db.t4models\linq2db.dll" #> diff --git a/Source/LinqToDB.Templates/LinqToDB.ttinclude b/Source/LinqToDB.Templates/LinqToDB.ttinclude deleted file mode 100644 index efa6700..0000000 --- a/Source/LinqToDB.Templates/LinqToDB.ttinclude +++ /dev/null @@ -1,882 +0,0 @@ -<#@ assembly name="System.Data" #> -<#@ import namespace="System.Data" #> -<#@ import namespace="LinqToDB.Data" #> -<#@ import namespace="System.Text" #> -<#@ include file="DataModel.ttinclude" #> -<# - if (BaseDataContextClass == null) - BaseDataContextClass = "LinqToDB.Data.DataConnection"; -#> -<#+ -Action BeforeGenerateLinqToDBModel = () => {}; -Action AfterGenerateLinqToDBModel = () => {}; - -Func GenerateProviderSpecificTable = t => null; - -bool GenerateObsoleteAttributeForAliases = false; -bool GenerateFindExtensions = true; -bool IsCompactColumns = true; -bool IsCompactColumnAliases = true; -bool GenerateDataTypes = false; -bool? GenerateLengthProperty = null; -bool? GeneratePrecisionProperty = null; -bool? GenerateScaleProperty = null; -bool GenerateDbTypes = false; -bool GenerateSchemaAsType = false; -bool GenerateViews = true; -string SchemaNameSuffix = "Schema"; -string SchemaDataContextTypeName = "DataContext"; - -Dictionary SchemaNameMapping = new Dictionary(); - -Func> GetConstructors = (conf, name) => GetConstructorsImpl(conf, name); - -static IEnumerable GetConstructorsImpl(string defaultConfiguration, string name) -{ - if (defaultConfiguration == null) - yield return new Method(null, name); - else - yield return new Method(null, name) { AfterSignature = { ": base(\"" + defaultConfiguration + "\")" } }; - yield return new Method(null, name, new[] { "string configuration" }) { AfterSignature = { ": base(configuration)" } }; -} - -void GenerateTypesFromMetadata() -{ - BeforeGenerateLinqToDBModel(); - - Model.Usings.Add("LinqToDB"); - Model.Usings.Add("LinqToDB.Mapping"); - - if (NamespaceName == null) - NamespaceName = "DataModel"; - - string schemaName; - - var schemas = - ( - from t in Tables.Values - where GenerateSchemaAsType && t.Schema != null && !t.TableSchema.IsDefaultSchema - group t by t.Schema into gr - orderby gr.Key - let typeName = SchemaNameMapping.TryGetValue(gr.Key, out schemaName) ? schemaName : gr.Key - select new - { - Name = gr.Key, - TypeName = typeName + SchemaNameSuffix, - PropertyName = typeName, - Props = new MemberGroup { IsCompact = true }, - Aliases = new MemberGroup { IsCompact = true, Region = "Alias members" }, - TableExtensions = new MemberGroup { Region = "Table Extensions" }, - Type = new Class(typeName + SchemaNameSuffix) { IsStatic = true }, - Tables = gr.ToList(), - DataContext = new Class(SchemaDataContextTypeName), - Procedures = new MemberGroup(), - Functions = new MemberGroup(), - TableFunctions = new MemberGroup { Region = "Table Functions" }, - } - ).ToDictionary(t => t.Name); - - var defProps = new MemberGroup { IsCompact = true }; - var defAliases = new MemberGroup { IsCompact = true, Region = "Alias members" }; - var defTableExtensions = new MemberGroup { }; - - if (schemas.Count > 0) - { - var body = new List(); - - var schemaGroup = new MemberGroup { Region = "Schemas" }; - var schemaMembers = new MemberGroup { IsCompact = true }; - - var maxLen1 = schemas.Values.Max(schema => schema.PropertyName.Trim().Length); - var maxLen2 = schemas.Values.Max(schema => schema.TypeName. Trim().Length); - - foreach (var schema in schemas.Values) - { - schemaMembers.Members.Add(new Property(schema.TypeName + "." + SchemaDataContextTypeName, schema.PropertyName)); - body.Add( - schema.PropertyName + LenDiff(maxLen1, schema.PropertyName) + - " = new " + schema.TypeName + "." + LenDiff(maxLen2, schema.TypeName) + - SchemaDataContextTypeName + "(this);"); - } - - schemaGroup.Members.Add(schemaMembers); - schemaGroup.Members.Add(new Method("void", "InitSchemas", new string[0], body)); - - DataContextObject.Members.Add(schemaGroup); - } - - if (GenerateConstructors) - { - foreach (var c in GetConstructors(DefaultConfiguration, DataContextObject.Name)) - { - if (c.Body.Count > 0) - c.Body.Add(""); - - if (schemas.Count > 0) - c.Body.Add("InitSchemas();"); - - c.Body.Add("InitDataContext();"); - - DataContextObject.Members.Add(c); - } - } - - DataContextObject.Members.Add(new MemberGroup - { - IsCompact = true, - Members = { new Method("void", "InitDataContext") { AccessModifier = AccessModifier.Partial } } - }); - - if (Tables.Count > 0) - DataContextObject.Members.Insert(0, defProps); - - foreach (var schema in schemas.Values) - { - schema.Type.Members.Add(schema.DataContext); - schema.DataContext.Members.Insert(0, schema.Props); - - schema.DataContext.Members.Add(new Field ("IDataContext", "_dataContext") { AccessModifier = AccessModifier.Private, IsReadonly = true }); - schema.DataContext.Members.Add(new Method(null, schema.DataContext.Name, new[] { "IDataContext dataContext" }, new[] { "_dataContext = dataContext;" })); - - foreach (var t in schema.Tables) - { - t.TypePrefix = schema.TypeName + "."; - } - } - - var associationExtensions = new MemberGroup() {Region = "Associations"}; - - foreach (var t in Tables.Values.OrderBy(tbl => tbl.IsProviderSpecific).ThenBy(tbl => tbl.TypeName)) - { - Action addType = tp => Model.Types.Add(tp); - var props = defProps; - var aliases = defAliases; - var tableExtensions = defTableExtensions; - - if (t.IsView && !GenerateViews){ - continue; - } - - var schema = t.Schema != null && schemas.ContainsKey(t.Schema) ? schemas[t.Schema] : null; - - if (schema != null) - { - var si = schemas[t.Schema]; - - addType = tp => si.Type.Members.Add(tp); - props = si.Props; - aliases = si.Aliases; - tableExtensions = si.TableExtensions; - } - - MemberBase dcProp = t.IsProviderSpecific ? - GenerateProviderSpecificTable(t) : - new Property( - string.Format("ITable<{0}>", t.TypeName), - t.DataContextPropertyName, - new[] { string.Format((schema == null ? "this" : "_dataContext") + ".GetTable<{0}>()", t.TypeName) }, - null); - - if (dcProp == null) continue; - - t.DataContextProperty = dcProp; - - props.Members.Add(dcProp); - - Property aProp = null; - - if (t.AliasPropertyName != null && t.AliasPropertyName != t.DataContextPropertyName) - { - aProp = new Property( - string.Format("ITable<{0}>", t.TypeName), - t.AliasPropertyName, - new[] { t.DataContextPropertyName }, - null); - - if (GenerateObsoleteAttributeForAliases) - aProp.Attributes.Add(new Attribute("Obsolete", "\"Use " + t.DataContextPropertyName + " instead.\"")); - - aliases.Members.Add(aProp); - } - - var tableAttrs = new List(); - - if (DatabaseName != null) tableAttrs.Add("Database=" + '"' + DatabaseName + '"'); - if (t.Schema != null) tableAttrs.Add("Schema=" + '"' + t.Schema + '"'); - - tableAttrs.Add((tableAttrs.Count == 0 ? "" : "Name=") + '"' + t.TableName + '"'); - - if (t.IsView) - tableAttrs.Add("IsView=true"); - - t.Attributes.Add(new Attribute("Table", tableAttrs.ToArray()) { IsSeparated = true } ); - - var comments = new List(); - - if (!string.IsNullOrWhiteSpace(t.Description)) - { - comments.Add("/ "); - foreach (var line in t.Description.Split('\n')) - comments.Add("/ " + line.TrimEnd()); - comments.Add("/ "); - } - - if (comments.Count > 0) - { - t. Comment.AddRange(comments); - dcProp.Comment.AddRange(comments); - - if (aProp != null) - aProp.Comment.AddRange(comments); - } - - var columns = new MemberGroup { IsCompact = IsCompactColumns }; - var columnAliases = new MemberGroup { IsCompact = IsCompactColumnAliases, Region = "Alias members" }; - var nPKs = t.Columns.Values.Count(c => c.IsPrimaryKey); - var allNullable = t.Columns.Values.All (c => c.IsNullable || c.IsIdentity); - var nameMaxLen = t.Columns.Values.Max (c => (int?)(c.MemberName == c.ColumnName - ? 0 - : NormalizeStringName(c.ColumnName).Length)) ?? 0; - var dbTypeMaxLen = t.Columns.Values.Max (c => (int?)(c.ColumnType.Length)) ?? 0; - var dataTypeMaxLen = t.Columns.Values.Where(c => c.DataType != null).Max (c => (int?)(c.DataType.Length)) ?? 0; - var dataTypePrefix = t.Columns.Values.Any (c => c.MemberName == "DataType") ? "LinqToDB." : ""; - - foreach (var c in t.Columns.Values) - { - // Column. - // - var ca = new Attribute("Column"); - var canBeReplaced = true; - - if (c.MemberName != c.ColumnName) - { - var columnNameInAttr = NormalizeStringName(c.ColumnName); - - var space = new string(' ', nameMaxLen - columnNameInAttr.Length); - - ca.Parameters.Add(columnNameInAttr + space); - canBeReplaced = false; - } - else if (nameMaxLen > 0) - { - ca.Parameters.Add(new string(' ', nameMaxLen)); - canBeReplaced = false; - } - - if (GenerateDbTypes) - { - var space = new string(' ', dbTypeMaxLen - c.ColumnType.Length); - - ca.Parameters.Add("DbType=\"" + c.ColumnType + '"' + space); - canBeReplaced = false; - } - - if (GenerateDataTypes) - { - var space = new string(' ', dataTypeMaxLen - c.DataType.Length); - ca.Parameters.Add("DataType=" + dataTypePrefix + c.DataType + space); - canBeReplaced = false; - } - - if (GenerateDataTypes && !GenerateLengthProperty.HasValue || GenerateLengthProperty == true) - { - if (c.Length != null) ca.Parameters.Add("Length=" + (c.Length == int.MaxValue ? "int.MaxValue" : c.Length.ToString())); - canBeReplaced = false; - } - - if (GenerateDataTypes && !GeneratePrecisionProperty.HasValue || GeneratePrecisionProperty == true) - { - if (c.Precision != null) ca.Parameters.Add("Precision=" + c.Precision); - canBeReplaced = false; - } - - if (GenerateDataTypes && !GenerateScaleProperty.HasValue || GenerateScaleProperty == true) - { - if (c.Scale != null) ca.Parameters.Add("Scale=" + c.Scale); - canBeReplaced = false; - } - - if (c.SkipOnInsert && !c.IsIdentity) - { - ca.Parameters.Add("SkipOnInsert=true"); - canBeReplaced = false; - } - - if (c.SkipOnUpdate && !c.IsIdentity) - { - ca.Parameters.Add("SkipOnUpdate=true"); - canBeReplaced = false; - } - - if (c.IsDiscriminator) - { - ca.Parameters.Add("IsDiscriminator=true"); - canBeReplaced = false; - } - - c.Attributes.Add(ca); - - // PK. - // - if (c.IsPrimaryKey) - { - var pka = new Attribute("PrimaryKey"); - - if (nPKs > 1) - pka.Parameters.Add(c.PrimaryKeyOrder.ToString()); - - if (canBeReplaced) - c.Attributes[0] = pka; - else - c.Attributes.Add(pka); - - canBeReplaced = false; - } - - // Identity. - // - if (c.IsIdentity) - { - var ida = new Attribute("Identity"); - - if (canBeReplaced) - c.Attributes[0] = ida; - else - c.Attributes.Add(ida); - - canBeReplaced = false; - } - - // Nullable. - // - if (c.IsNullable) - c.Attributes.Add(new Attribute((allNullable ? "" : " ") + "Nullable")); - else if (!c.IsIdentity) - c.Attributes.Add(new Attribute("NotNull")); - - var columnComments = new List(); - - if (!string.IsNullOrWhiteSpace(c.Description)) - { - columnComments.Add("/ "); - foreach (var line in c.Description.Split('\n')) - columnComments.Add("/ " + line.TrimEnd()); - columnComments.Add("/ "); - } - - if (columnComments.Count > 0) - c.Comment.AddRange(columnComments); - - // End line comment. - // - c.EndLineComment = c.ColumnType; - - SetPropertyValue(c, "IsNotifying", true); - SetPropertyValue(c, "IsEditable", true); - - columns.Members.Add(c); - - // Alias. - // - if (c.AliasName != null && c.AliasName != c.MemberName) - { - var caProp = new Property( - c.Type, - c.AliasName, - new[] { c.MemberName }, - new[] { c.MemberName + " = value;"}); - - caProp.Comment.AddRange(columnComments); - - if (GenerateObsoleteAttributeForAliases) - caProp.Attributes.Add(new Attribute("Obsolete", "\"Use " + c.MemberName + " instead.\"")); - - caProp.Attributes.Add(new Attribute("ColumnAlias", "\"" + c.MemberName + "\"")); - - columnAliases.Members.Add(caProp); - } - } - - t.Members.Add(columns); - - if (columnAliases.Members.Count > 0) - t.Members.Add(columnAliases); - - if (GenerateAssociations || GenerateAssociationExtensions) - { - var keys = t.ForeignKeys.Values.ToList(); - - if (!GenerateBackReferences) - keys = keys.Where(k => k.BackReference != null).ToList(); - - if (keys.Count > 0) - { - var associations = new MemberGroup { Region = "Associations" }; - var extensionAssociations = new MemberGroup { Region = t.Name + " Associations"}; - - foreach (var key in keys.OrderBy(k => k.MemberName)) - { - key.Comment.Add("/ "); - key.Comment.Add("/ " + key.KeyName); - key.Comment.Add("/ "); - - if (key.AssociationType == AssociationType.OneToMany) - key.Type = string.Format(OneToManyAssociationType, key.OtherTable.TypePrefix + key.OtherTable.TypeName); - else - key.Type = key.OtherTable.TypePrefix + key.OtherTable.TypeName; - - var aa = new Attribute("Association"); - - aa.Parameters.Add("ThisKey=\"" + string.Join(", ", (from c in key.ThisColumns select c.MemberName).ToArray()) + "\""); - aa.Parameters.Add("OtherKey=\"" + string.Join(", ", (from c in key.OtherColumns select c.MemberName).ToArray()) + "\""); - aa.Parameters.Add("CanBeNull=" + (key.CanBeNull ? "true" : "false")); - - switch (key.AssociationType) - { - case AssociationType.OneToOne : aa.Parameters.Add("Relationship=Relationship.OneToOne"); break; - case AssociationType.OneToMany : aa.Parameters.Add("Relationship=Relationship.OneToMany"); break; - case AssociationType.ManyToOne : aa.Parameters.Add("Relationship=Relationship.ManyToOne"); break; - } - - if (key.BackReference != null) - { - if (!string.IsNullOrEmpty(key.KeyName)) - aa.Parameters.Add("KeyName=\"" + key.KeyName + "\""); - if (GenerateBackReferences && !string.IsNullOrEmpty(key.BackReference.MemberName)) - aa.Parameters.Add("BackReferenceName=\"" + key.BackReference.MemberName + "\""); - } - else - { - aa.Parameters.Add("IsBackReference=true"); - } - - key.Attributes.Add(aa); - - SetPropertyValue(key, "IsNotifying", true); - SetPropertyValue(key, "IsEditable", true); - - associations.Members.Add(key); - - var extension = new Method(string.Format("IQueryable<{0}>", key.OtherTable.TypePrefix + key.OtherTable.TypeName), GetAssociationExtensionPluralName(key)); - extension.Parameters.Add(string.Format("this {0} obj", t.TypeName)); - extension.Parameters.Add("IDataContext db"); - extension.Attributes.Add(aa); - extension.IsStatic = true; - - extension.Comment.Add("/ "); - extension.Comment.Add("/ " + key.KeyName); - extension.Comment.Add("/ "); - - - var sb = new StringBuilder(); - sb - .Append("return db.GetTable<") - .Append(key.OtherTable.TypePrefix + key.OtherTable.TypeName) - .Append(">().Where(c => "); - for (var i = 0; i < key.OtherColumns.Count; i++) - { - sb.Append("c.") - .Append(key.OtherColumns[i].MemberName) - .Append(" == obj.") - .Append(key.ThisColumns[i].MemberName) - .Append(" && "); - } - sb.Length -= 4; - sb.Append(");"); - - - extension.Body.Add(sb.ToString()); - - extensionAssociations.Members.Add(extension); - - if (key.AssociationType != AssociationType.OneToMany) - { - extension.Name = GetAssociationExtensionPluralName(key); - - var single = new Method(key.OtherTable.TypePrefix + key.OtherTable.TypeName, GetAssociationExtensionSinglularName(key)); - single.Parameters.Add(string.Format("this {0} obj", t.TypeName)); - single.Parameters.Add("IDataContext db"); - single.Attributes.Add(aa); - single.IsStatic = true; - - single.Comment.Add("/ "); - single.Comment.Add("/ " + key.KeyName); - single.Comment.Add("/ "); - - sb.Length -= 1; - - if (key.CanBeNull) - sb.Append(".FirstOrDefault();"); - else - sb.Append(".First();"); - - single.Body.Add(sb.ToString()); - - extensionAssociations.Members.Add(single); - } - - - } - - if (GenerateAssociations) - t.Members.Add(associations); - if (GenerateAssociationExtensions) - associationExtensions.Members.Add(extensionAssociations); - } - } - - if (GenerateFindExtensions && nPKs > 0) - { - var PKs = t.Columns.Values.Where(c => c.IsPrimaryKey).ToList(); - var maxNameLen1 = PKs.Max(c => (int?)c.MemberName.Length) ?? 0; - var maxNameLen2 = PKs.Take(nPKs - 1).Max(c => (int?)c.MemberName.Length) ?? 0; - - tableExtensions.Members.Add( - new Method( - t.TypeName, - "Find", - new[] { (string.Format("this ITable<{0}> table", t.TypeName)) } - .Union(PKs.Select(c => c.Type + " " + c.MemberName)), - new[] { "return table.FirstOrDefault(t =>" } - .Union(PKs.SelectMany((c,i) => - { - var ss = new List(); - - if (c.Conditional != null) - ss.Add("#if " + c.Conditional); - - ss.Add(string.Format("\tt.{0}{1} == {0}{3}{2}", - c.MemberName, LenDiff(maxNameLen1, c.MemberName), i == nPKs - 1 ? ");" : " &&", i == nPKs - 1 ? "" : LenDiff(maxNameLen2, c.MemberName))); - - if (c.Conditional != null) - { - if (ss[1].EndsWith(");")) - { - ss[1] = ss[1].Substring(0, ss[1].Length - 2); - ss.Add("#endif"); - ss.Add("\t\t);"); - } - else - { - ss.Add("#endif"); - } - } - - return ss; - }))) - { - IsStatic = true - }); - } - - addType(t); - - if (!string.IsNullOrWhiteSpace(t.AliasTypeName)) - { - var aClass = new Class(t.AliasTypeName) - { - BaseClass = t.TypeName - }; - - if (comments.Count > 0) - aClass.Comment.AddRange(comments); - - if (GenerateObsoleteAttributeForAliases) - aClass.Attributes.Add(new Attribute("Obsolete", "\"Use " + t.TypeName + " instead.\"")); - - Model.Types.Add(aClass); - } - - } - - if (associationExtensions.Members.Count > 0) - defTableExtensions.Members.Add(associationExtensions); - - if (defAliases.Members.Count > 0) - DataContextObject.Members.Add(defAliases); - - foreach (var schema in schemas.Values) - if (schema.Aliases.Members.Count > 0) - schema.Type.Members.Add(defAliases); - - if (Procedures.Count > 0) - { - Model.Usings.Add("System.Collections.Generic"); - Model.Usings.Add("System.Data"); - Model.Usings.Add("LinqToDB.Data"); - Model.Usings.Add("LinqToDB.Common"); - - if (Procedures.Values.Any(p => p.IsTableFunction)) - Model.Usings.Add("System.Reflection"); - - var procs = new MemberGroup(); - var funcs = new MemberGroup(); - var tabfs = new MemberGroup { Region = "Table Functions" }; - - foreach (var p in Procedures.Values.Where( - proc => proc.IsLoaded || proc.IsFunction && !proc.IsTableFunction || - proc.IsTableFunction && proc.ResultException != null - )) - { - Action addProcs = tp => procs.Members.Add(tp); - Action addFuncs = tp => funcs.Members.Add(tp); - Action addTabfs = tp => tabfs.Members.Add(tp); - - var thisDataContext = "this"; - - var schema = p.Schema != null && schemas.ContainsKey(p.Schema) ? schemas[p.Schema] : null; - - if (schema != null) - { - var si = schemas[p.Schema]; - - addProcs = tp => si.Procedures. Members.Add(tp); - addFuncs = tp => si.Functions. Members.Add(tp); - addTabfs = tp => si.TableFunctions.Members.Add(tp); - thisDataContext = "_dataContext"; - } - - var proc = new MemberGroup { Region = p.Name }; - - if (!p.IsFunction) addProcs(proc); - else if (p.IsTableFunction) addTabfs(proc); - else addFuncs(proc); - - if (p.ResultException != null) - { - proc.Errors.Add(p.ResultException.Message); - continue; - } - - proc.Members.Add(p); - - if (p.IsTableFunction) - { - var tableAttrs = new List(); - - if (DatabaseName != null) tableAttrs.Add("Database=" + '"' + DatabaseName + '"'); - if (p.Schema != null) tableAttrs.Add("Schema=" + '"' + p.Schema + '"'); - - tableAttrs.Add("Name=" + '"' + p.ProcedureName + '"'); - - p.Attributes.Add(new Attribute("Sql.TableFunction", tableAttrs.ToArray())); - - p.Type = "ITable<" + p.ResultTable.TypeName + ">"; - } - else if (p.IsFunction) - { - p.IsStatic = true; - p.Type = p.ProcParameters.Single(pr => pr.IsResult).ParameterType; - p.Attributes.Add(new Attribute("Sql.Function", "Name=\"" + p.Schema + "." + p.ProcedureName + "\"", "ServerSideOnly=true")); - } - else - { - p.IsStatic = true; - p.Type = p.ResultTable == null ? "int" : "IEnumerable<" + p.ResultTable.TypeName + ">"; - p.Parameters.Add("this DataConnection dataConnection"); - } - - foreach (var pr in p.ProcParameters.Where(par => !par.IsResult)) - p.Parameters.Add(string.Format("{0}{1} {2}", - pr.IsOut ? pr.IsIn ? "ref " : "out " : "", pr.ParameterType, pr.ParameterName)); - - if (p.IsTableFunction) - { - var body = string.Format("return " + thisDataContext + ".GetTable<{0}>(this, (MethodInfo)MethodBase.GetCurrentMethod()", p.ResultTable.TypeName); - - body += p.ProcParameters.Count == 0 ? ");" : ","; - - p.Body.Add(body); - - for (var i = 0; i < p.ProcParameters.Count; i++) - p.Body.Add("\t" + p.ProcParameters[i].ParameterName + (i + 1 == p.ProcParameters.Count ? ");" : ",")); - } - else if (p.IsFunction) - { - p.Body.Add("throw new InvalidOperationException();"); - } - else - { - var spName = - SqlBuilder.BuildTableName( - new System.Text.StringBuilder(), - (string)SqlBuilder.Convert(DatabaseName, LinqToDB.SqlProvider.ConvertType.NameToDatabase), - (string)SqlBuilder.Convert(p.Schema, LinqToDB.SqlProvider.ConvertType.NameToOwner), - (string)SqlBuilder.Convert(p.ProcedureName, LinqToDB.SqlProvider.ConvertType.NameToQueryTable) - ).ToString(); - - spName = "\"" + spName.Replace("\"", "\\\"") + "\""; - - var inputParameters = p.ProcParameters.Where(pp => pp.IsIn). ToList(); - var outputParameters = p.ProcParameters.Where(pp => pp.IsOut).ToList(); - - spName += inputParameters.Count == 0 ? ");" : ","; - - var retName = "ret"; - var retNo = 0; - - while (p.ProcParameters.Any(pp => pp.ParameterName == retName)) - retName = "ret" + ++retNo; - - var hasOut = outputParameters.Any(pr => pr.IsOut); - var prefix = hasOut ? "var " + retName + " = " : "return "; - - if (p.ResultTable == null) - p.Body.Add(prefix + "dataConnection.ExecuteProc(" + spName); - else - { - if (p.ResultTable.Columns.Values.Any(c => c.IsDuplicateOrEmpty)) - { - p.Body.Add("var ms = dataConnection.MappingSchema;"); - p.Body.Add(""); - p.Body.Add(prefix + "dataConnection.QueryProc(dataReader =>"); - p.Body.Add("\tnew " + p.ResultTable.TypeName); - p.Body.Add("\t{"); - - var n = 0; - var maxNameLen = p.ResultTable.Columns.Values.Max(c => (int?)c.MemberName.Length) ?? 0; - var maxTypeLen = p.ResultTable.Columns.Values.Max(c => (int?)c.Type. Length) ?? 0; - - foreach (var c in p.ResultTable.Columns.Values) - { - p.Body.Add(string.Format("\t\t{0}{1} = Converter.ChangeTypeTo<{2}>{3}(dataReader.GetValue({4}), ms),", - c.MemberName, LenDiff(maxNameLen, c.MemberName), c.Type, LenDiff(maxTypeLen, c.Type), n++)); - } - - p.Body.Add("\t},"); - p.Body.Add("\t" + spName); - } - else - { - p.Body.Add(prefix + "dataConnection.QueryProc<" + p.ResultTable.TypeName + ">(" + spName); - } - } - - var maxLenSchema = inputParameters.Max(pr => (int?)pr.SchemaName. Length) ?? 0; - var maxLenParam = inputParameters.Max(pr => (int?)pr.ParameterName.Length) ?? 0; - var maxLenType = inputParameters.Max(pr => (int?)("DataType." + pr.DataType).Length) ?? 0; - - for (var i = 0; i < inputParameters.Count; i++) - { - var pr = inputParameters[i]; - - var str = string.Format("\tnew DataParameter(\"{0}\", {1}{2}, {3}{4})", - pr.SchemaName, - LenDiff(maxLenSchema, pr.SchemaName), - pr.ParameterName, - LenDiff(maxLenParam, pr.ParameterName), - "DataType." + pr.DataType); - - if (pr.IsOut) - { - str += LenDiff(maxLenType, "DataType." + pr.DataType); - str += " { Direction = " + (pr.IsIn ? "ParameterDirection.InputOutput" : "ParameterDirection.Output"); - - if (pr.Size != null && pr.Size.Value != 0) - str += ", Size = " + pr.Size.Value; - - str += " }"; - } - - str += i + 1 == inputParameters.Count ? ");" : ","; - - p.Body.Add(str); - } - - if (hasOut) - { - maxLenSchema = outputParameters.Max(pr => (int?)pr.SchemaName. Length) ?? 0; - maxLenParam = outputParameters.Max(pr => (int?)pr.ParameterName.Length) ?? 0; - maxLenType = outputParameters.Max(pr => (int?)pr.ParameterType.Length) ?? 0; - - p.Body.Add(""); - - foreach (var pr in p.ProcParameters.Where(_ => _.IsOut)) - { - var str = string.Format("{0} {1}= Converter.ChangeTypeTo<{2}>{3}(((IDbDataParameter)dataConnection.Command.Parameters[\"{4}\"]).{5}Value);", - pr.ParameterName, - LenDiff(maxLenParam, pr.ParameterName), - pr.ParameterType, - LenDiff(maxLenType, pr.ParameterType), - pr.SchemaName, - LenDiff(maxLenSchema, pr.SchemaName)); - - p.Body.Add(str); - } - - p.Body.Add(""); - p.Body.Add("return " + retName + ";"); - } - } - - if (p.ResultTable != null && p.ResultTable.DataContextPropertyName == null) - { - var columns = new MemberGroup { IsCompact = true }; - - foreach (var c in p.ResultTable.Columns.Values) - { - if (c.MemberName != c.ColumnName) - c.Attributes.Add(new Attribute("Column") { Parameters = { NormalizeStringName(c.ColumnName) } }); - columns.Members.Add(c); - } - - p.ResultTable.Members.Add(columns); - proc.Members.Add(p.ResultTable); - } - } - - if (procs.Members.Count > 0) - Model.Types.Add(new Class(DataContextObject.Name + "StoredProcedures", procs) { IsStatic = true }); - - if (funcs.Members.Count > 0) - Model.Types.Add(new Class("SqlFunctions", funcs) { IsStatic = true }); - - if (tabfs.Members.Count > 0) - DataContextObject.Members.Add(tabfs); - - foreach (var schema in schemas.Values) - { - if (schema.Procedures.Members.Count > 0) - schema.Type.Members.Add(new Class(DataContextObject.Name + "StoredProcedures", schema.Procedures) { IsStatic = true }); - - if (schema.Functions.Members.Count > 0) - schema.Type.Members.Add(new Class("SqlFunctions", schema.Functions) { IsStatic = true }); - - if (schema.TableFunctions.Members.Count > 0) - schema.DataContext.Members.Add(schema.TableFunctions); - } - } - - if (defTableExtensions.Members.Count > 0) - { - Model.Usings.Add("System.Linq"); - Model.Types.Add(new Class("TableExtensions", defTableExtensions) { IsStatic = true }); - } - - foreach (var schema in schemas.Values) - { - Model.Types.Add(schema.Type); - - if (schema.TableExtensions.Members.Count > 0) - { - Model.Usings.Add("System.Linq"); - schema.Type.Members.Add(schema.TableExtensions); - } - } - - Tables. Clear(); - Procedures.Clear(); - - Model.SetTree(); - - AfterGenerateLinqToDBModel(); -} - -string NormalizeStringName(string name) -{ - if (name.Contains("\"") || name.Contains("\\")) - return @"@""" + name.Replace(@"""", @"""""") + @""""; - return "\"" + name + "\""; -} - -#> diff --git a/Source/LinqToDB.Templates/MultipleFiles.ttinclude b/Source/LinqToDB.Templates/MultipleFiles.ttinclude deleted file mode 100644 index 4b43ba0..0000000 --- a/Source/LinqToDB.Templates/MultipleFiles.ttinclude +++ /dev/null @@ -1,70 +0,0 @@ -<#@ assembly name="System.Core" #> -<#@ assembly name="EnvDTE" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.IO" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="EnvDTE" #> -<#+ -DTE _dte; -DTE DTE => _dte ?? (_dte = (DTE)((IServiceProvider)Host).GetService(typeof(DTE))); - -ProjectItem _templateProjectItem; -ProjectItem TemplateProjectItem => _templateProjectItem ?? (_templateProjectItem = DTE.Solution.FindProjectItem(Host.TemplateFile)); - -readonly Dictionary _fileNames = new Dictionary(); - -Func CompareContent = (s1,s2) => s1 == s2; - -void SaveOutput(string fileName, int fileType = 1) -{ - var dir = Path.GetDirectoryName(Host.TemplateFile); - var output = Path.Combine(dir, fileName); - var newContent = GenerationEnvironment.ToString(); - var oldContent = File.Exists(output) ? File.ReadAllText(output) : ""; - - if (!CompareContent(newContent, oldContent)) - { - if (DTE.SourceControl != null && DTE.SourceControl.IsItemUnderSCC(output) && !DTE.SourceControl.IsItemCheckedOut(output)) - DTE.SourceControl.CheckOutItem(output); - - File.WriteAllText(output, newContent); - } - - GenerationEnvironment.Length = 0; - - _fileNames.Add(output, fileType); -} - -void SyncProject() -{ - var keepFileNames = _fileNames.ToDictionary(f => f.Key); - var projectFiles = new Dictionary(); - var templateFileName = TemplateProjectItem.FileNames[0]; - var originalFilePrefix = Path.GetFileNameWithoutExtension(templateFileName) + "."; - - foreach (ProjectItem projectItem in TemplateProjectItem.ProjectItems) - { - projectFiles.Add(projectItem.FileNames[0], projectItem); - } - - foreach (var pair in projectFiles) - { - if (!keepFileNames.ContainsKey(pair.Key)) - if (!(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix)) - //if (pair.Key != templateFileName) - pair.Value.Delete(); - } - - // Add missing files to the project. - // - foreach (var fileName in keepFileNames) - { - if (!projectFiles.ContainsKey(fileName.Value.Key)) - if (File.Exists(fileName.Value.Key)) - { - var newItem = TemplateProjectItem.ProjectItems.AddFromFile(fileName.Value.Key); - newItem.Properties.Item("BuildAction").Value = fileName.Value.Value; - } - } -} -#> diff --git a/Source/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude b/Source/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude deleted file mode 100644 index 4663038..0000000 --- a/Source/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude +++ /dev/null @@ -1,133 +0,0 @@ -<# - { - var beforeGenerateModel = BeforeGenerateModel; - BeforeGenerateModel = () => - { - beforeGenerateModel(); - NotifyDataErrorInfoImpl(); - }; - } -#> -<#+ -void NotifyDataErrorInfoImpl() -{ - foreach (var prop in GetTreeNodes(Model).OfType().Where(p => p.CustomValidation).ToList()) - { - ITree p = prop.Parent; - - while (!(p is Class) && p != null) - p = p.Parent; - - if (p != null) - { - var cl = (Class)p; - - if (!cl.Interfaces.Contains("INotifyDataErrorInfo")) - { - if (!Model.Usings.Contains("System.ComponentModel")) Model.Usings.Add("System.ComponentModel"); - if (!Model.Usings.Contains("System.Collections")) Model.Usings.Add("System.Collections"); - if (!Model.Usings.Contains("System.Linq")) Model.Usings.Add("System.Linq"); - - cl.Interfaces.Add("INotifyDataErrorInfo"); - - cl.Members.Add(new MemberGroup - { - Region = "INotifyDataErrorInfo support", - Members = - { - new Event("EventHandler", "ErrorsChanged") - { - IsVirtual = true, - Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } - }, - new Field("Dictionary>", "_validationErrors") - { - InitValue = "new Dictionary>()", - AccessModifier = AccessModifier.Private, - IsReadonly = true, - Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } - }, - new Method("void", "AddError", - new[] - { - "string propertyName", - "string error" - }, - new[] - { - "List errors;", - "", - "if (!_validationErrors.TryGetValue(propertyName, out errors))", - "{", - "\t_validationErrors[propertyName] = new List { error };", - "}", - "else if (!errors.Contains(error))", - "{", - "\terrors.Add(error);", - "}", - "else", - "\treturn;", - "", - "OnErrorsChanged(propertyName);", - }) - { - AccessModifier = AccessModifier.Public - }, - new Method("void", "RemoveError", - new[] - { - "string propertyName", - }, - new[] - { - "List errors;", - "", - "if (_validationErrors.TryGetValue(propertyName, out errors) && errors.Count > 0)", - "{", - "\t_validationErrors.Clear();", - "\tOnErrorsChanged(propertyName);", - "}", - }) - { - AccessModifier = AccessModifier.Public - }, - new Method("void", "OnErrorsChanged", - new[] - { - "string propertyName", - }, - new[] - { - "if (ErrorsChanged != null)", - "{", - "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", - "\t\tErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));", - "\telse", - "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", - "\t\t\t() => ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName)));", - "}", - }) - { - AccessModifier = AccessModifier.Protected - }, - new Method("IEnumerable", "GetErrors", - new[] - { - "string propertyName", - }, - new[] - { - "List errors;", - "return propertyName != null && _validationErrors.TryGetValue(propertyName, out errors) ? errors : null;", - }) - { - AccessModifier = AccessModifier.Public - }, - new Property("bool", "HasErrors").InitGetter("_validationErrors.Values.Any(e => e.Count > 0)") - } - }); - } - } - } -} -#> diff --git a/Source/LinqToDB.Templates/NotifyPropertyChanged.ttinclude b/Source/LinqToDB.Templates/NotifyPropertyChanged.ttinclude deleted file mode 100644 index eda008e..0000000 --- a/Source/LinqToDB.Templates/NotifyPropertyChanged.ttinclude +++ /dev/null @@ -1,380 +0,0 @@ -<# - { - var beforeGenerateModel = BeforeGenerateModel; - BeforeGenerateModel = () => - { - beforeGenerateModel(); - NotifyPropertyChangedImpl(); - }; - - SetPropertyValueAction += (obj,prop,val) => - { - if (prop == "IsNotifying") - obj.IsNotifying = (bool)val; - }; - } -#><#+ -public bool ImplementNotifyPropertyChanging; -public bool SkipNotifyPropertyChangedImplementation = false; - -void NotifyPropertyChangedImpl() -{ - foreach (Property prop in GetTreeNodes(Model).OfType().Where(p => p.IsNotifying).ToList()) - { - List parentMembers; - - MemberGroup gr = null; - - if (prop.Parent is Class) - { - var parent = (Class)prop.Parent; - parentMembers = parent.Members; - } - else - { - var parent = (MemberGroup)prop.Parent; - - parent.IsCompact = false; - - parentMembers = parent.Members; - - if (parent.IsPropertyGroup) - gr = parent; - } - - var name = prop.Name.Trim(); - var type = prop.Type.Trim(); - - if (gr == null) - { - gr = new MemberGroup - { - Region = name + " : " + type, - Members = { prop }, - IsPropertyGroup = true, - }; - - var index = parentMembers.IndexOf(prop); - - parentMembers.RemoveAt(index); - parentMembers.Insert (index, gr); - } - - if (prop.IsAuto) - { - var field = new Field(type, "_" + ToCamelCase(name)) - { - AccessModifier = AccessModifier.Private, - InsertBlankLineAfter = false, - }; - - if (prop.InitValue != null) - field.InitValue = prop.InitValue; - - gr.Members.Insert(0, field); - - prop.Name = " " + name; - prop.Type = " " + type; - prop.IsAuto = false; - - if (prop.HasGetter) prop.GetBody.Add("return " + field.Name + ";"); - if (prop.HasSetter) prop.SetBody.Add(field.Name + " = value;"); - } - - var methods = new MemberGroup - { - Region = "INotifyPropertyChanged support", - Members = - { - new Field("const string", "NameOf" + name) - { - InitValue = "\"" + name + "\"", - AccessModifier = AccessModifier.Public, - }, - new Field("PropertyChangedEventArgs", "_" + ToCamelCase(name) + "ChangedEventArgs") - { - InitValue = "new PropertyChangedEventArgs(NameOf" + name + ")", - AccessModifier = AccessModifier.Private, - IsStatic = true, - IsReadonly = true, - }, - new Method("void", "On" + name + "Changed", null, - new[] { "OnPropertyChanged(_" + ToCamelCase(name) + "ChangedEventArgs);" }) - { - AccessModifier = AccessModifier.Private - } - } - }; - - gr.Members.Add(methods); - - if (prop.Dependents.Count == 0) - prop.Dependents.Add(name); - - if (ImplementNotifyPropertyChanging) - { - gr.Members.Add(new MemberGroup - { - Region = "INotifyPropertyChanging support", - Members = - { - new Field("PropertyChangingEventArgs", "_" + ToCamelCase(name) + "ChangingEventArgs") - { - InitValue = "new PropertyChangingEventArgs(NameOf" + name + ")", - AccessModifier = AccessModifier.Private, - IsStatic = true, - IsReadonly = true, - }, - new Method("void", "On" + name + "Changing", null, - new[] { "OnPropertyChanging(_" + ToCamelCase(name) + "ChangingEventArgs);" }) - { - AccessModifier = AccessModifier.Private - } - } - }); - } - - if (prop.HasSetter) - { - prop.SetBody = prop.SetBody.Select(s => "\t" + s).ToList(); - - string getValue; - - if (prop.GetBody.Count == 1 && prop.GetBody[0].StartsWith("return")) - { - getValue = prop.GetBody[0].Substring("return".Length).Trim(' ', '\t', ';'); - } - else - { - getValue = name; - } - - var insSpaces = prop.SetBody.Count > 1; - var n = 0; - - prop.SetBody.Insert(n++, "if (" + getValue + " != value)"); - prop.SetBody.Insert(n++, "{"); - - if (ImplementNotifyPropertyChanging) - { - foreach (var dp in prop.Dependents) - prop.SetBody.Insert(n++, "\tOn" + dp + "Changing();"); - prop.SetBody.Insert(n++, ""); - } - - prop.SetBody.Insert(n++, "\tBefore" + name + "Changed(value);"); - - if (insSpaces) - { - prop.SetBody.Insert(3, ""); - prop.SetBody.Add(""); - } - - prop.SetBody.Add("\tAfter" + name + "Changed();"); - prop.SetBody.Add(""); - - foreach (var dp in prop.Dependents) - prop.SetBody.Add("\tOn" + dp + "Changed();"); - - prop.SetBody.Add("}"); - - methods.Members.Insert(0, new MemberGroup - { - IsCompact = true, - Members = - { - new Method("void", "Before" + name + "Changed", new[] { type + " newValue" }) { AccessModifier = AccessModifier.Partial }, - new Method("void", "After" + name + "Changed") { AccessModifier = AccessModifier.Partial }, - } - }); - } - - prop.Parent.SetTree(); - - ITree p = prop.Parent; - - while (!(p is Class) && p != null) - p = p.Parent; - - if (p != null) - { - var cl = (Class)p; - - if (!SkipNotifyPropertyChangedImplementation && !cl.Interfaces.Contains("INotifyPropertyChanged")) - { - if (!Model.Usings.Contains("System.ComponentModel")) - Model.Usings.Add("System.ComponentModel"); - - cl.Interfaces.Add("INotifyPropertyChanged"); - - cl.Members.Add(new MemberGroup - { - Region = "INotifyPropertyChanged support", - Members = - { - new Event("PropertyChangedEventHandler", "PropertyChanged") - { - IsVirtual = true, - Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } - }, - new Method("void", "OnPropertyChanged", new[] { "string propertyName" }, OnPropertyChangedBody) - { - AccessModifier = AccessModifier.Protected - }, - new Method("void", "OnPropertyChanged", new[] { "PropertyChangedEventArgs arg" }, OnPropertyChangedArgBody) - { - AccessModifier = AccessModifier.Protected - }, - } - }); - } - - if (ImplementNotifyPropertyChanging && !cl.Interfaces.Contains("INotifyPropertyChanging")) - { - if (!Model.Usings.Contains("System.ComponentModel")) - Model.Usings.Add("System.ComponentModel"); - - cl.Interfaces.Add("INotifyPropertyChanging"); - - cl.Members.Add(new MemberGroup - { - Region = "INotifyPropertyChanging support", - Members = - { - new Event("PropertyChangingEventHandler", "PropertyChanging") - { - IsVirtual = true, - Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } - }, - new Method("void", "OnPropertyChanging", new[] { "string propertyName" }, OnPropertyChangingBody) - { - AccessModifier = AccessModifier.Protected - }, - new Method("void", "OnPropertyChanging", new[] { "PropertyChangingEventArgs arg" }, OnPropertyChangingArgBody) - { - AccessModifier = AccessModifier.Protected - }, - } - }); - } - } - } -} - -public string[] OnPropertyChangedBody = new[] -{ - "var propertyChanged = PropertyChanged;", - "", - "if (propertyChanged != null)", - "{", - "#if SILVERLIGHT", - "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", - "\t\tpropertyChanged(this, new PropertyChangedEventArgs(propertyName));", - "\telse", - "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", - "\t\t\t() =>", - "\t\t\t{", - "\t\t\t\tvar pc = PropertyChanged;", - "\t\t\t\tif (pc != null)", - "\t\t\t\t\tpc(this, new PropertyChangedEventArgs(propertyName));", - "\t\t\t});", - "#else", - "\tpropertyChanged(this, new PropertyChangedEventArgs(propertyName));", - "#endif", - "}", -}; - -public string[] OnPropertyChangedArgBody = new[] -{ - "var propertyChanged = PropertyChanged;", - "", - "if (propertyChanged != null)", - "{", - "#if SILVERLIGHT", - "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", - "\t\tpropertyChanged(this, arg);", - "\telse", - "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", - "\t\t\t() =>", - "\t\t\t{", - "\t\t\t\tvar pc = PropertyChanged;", - "\t\t\t\tif (pc != null)", - "\t\t\t\t\tpc(this, arg);", - "\t\t\t});", - "#else", - "\tpropertyChanged(this, arg);", - "#endif", - "}", -}; - -public string[] OnPropertyChangingBody = new[] -{ - "var propertyChanging = PropertyChanging;", - "", - "if (propertyChanging != null)", - "{", - "#if SILVERLIGHT", - "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", - "\t\tpropertyChanging(this, new PropertyChangingEventArgs(propertyName));", - "\telse", - "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", - "\t\t\t() =>", - "\t\t\t{", - "\t\t\t\tvar pc = PropertyChanging;", - "\t\t\t\tif (pc != null)", - "\t\t\t\t\tpc(this, new PropertyChangingEventArgs(propertyName));", - "\t\t\t});", - "#else", - "\tpropertyChanging(this, new PropertyChangingEventArgs(propertyName));", - "#endif", - "}", -}; - -public string[] OnPropertyChangingArgBody = new[] -{ - "var propertyChanging = PropertyChanging;", - "", - "if (propertyChanging != null)", - "{", - "#if SILVERLIGHT", - "\tif (System.Windows.Deployment.Current.Dispatcher.CheckAccess())", - "\t\tpropertyChanging(this, arg);", - "\telse", - "\t\tSystem.Windows.Deployment.Current.Dispatcher.BeginInvoke(", - "\t\t\t() =>", - "\t\t\t{", - "\t\t\t\tvar pc = PropertyChanging;", - "\t\t\t\tif (pc != null)", - "\t\t\t\t\tpc(this, arg);", - "\t\t\t});", - "#else", - "\tpropertyChanging(this, arg);", - "#endif", - "}", -}; - -partial class Property -{ - public bool IsNotifying; - public List Dependents = new List(); -} - -class NotifyingProperty : Property -{ - public NotifyingProperty() - { - IsNotifying = true; - } - - public NotifyingProperty(string type, string name, params string[] dependents) - : base(type, name, null, null) - { - IsNotifying = true; - - if (dependents.Length == 0) - Dependents.Add(name); - else - Dependents.AddRange(dependents); - } -} -#> diff --git a/Source/LinqToDB.Templates/ObsoleteAttributes.ttinclude b/Source/LinqToDB.Templates/ObsoleteAttributes.ttinclude deleted file mode 100644 index 94f1b05..0000000 --- a/Source/LinqToDB.Templates/ObsoleteAttributes.ttinclude +++ /dev/null @@ -1,100 +0,0 @@ -<# - { - var beforeGenerateLinqToDBModel = BeforeGenerateLinqToDBModel; - var afterGenerateLinqToDBModel = AfterGenerateLinqToDBModel; - - var obsoleteTables = new List>(); - - BeforeGenerateLinqToDBModel = () => - { - beforeGenerateLinqToDBModel(); - - foreach (var table in Tables.Values) - { - var idx = table.Description.IndexOf("[Obsolete"); - - if (idx >= 0) - { - var idx2 = table.Description.IndexOf(']', idx); - - if (idx2 > idx) - { - var text = table.Description.Substring(idx + 1, idx2 - idx - 1); - var attr = new Attribute(text); - var info = Tuple.Create(table.Schema, table.Name, text); - - if (obsoleteTables.All(a => a != info)) - obsoleteTables.Add(info); - table.Attributes.Add(attr); - table.Description = table.Description.Substring(0, idx) + table.Description.Substring(idx2 + 1); - } - } - - foreach (var c in table.Columns.Values) - { - idx = c.Description.IndexOf("[Obsolete"); - - if (idx >= 0) - { - var idx2 = c.Description.IndexOf(']', idx); - - if (idx2 > idx) - { - var attr = new Attribute(c.Description.Substring(idx + 1, idx2 - idx - 1)); - - c.Attributes.Add(attr); - c.Description = c.Description.Substring(0, idx) + c.Description.Substring(idx2 + 1); - } - } - } - } - }; - - AfterGenerateLinqToDBModel = () => - { - foreach (var tableInfo in obsoleteTables) - { - var schema = tableInfo.Item1; - var name = tableInfo.Item2; - var text = tableInfo.Item3; - var obsoleteAttr = new Attribute(text); - - foreach (var cm in GetTreeNodes(Model) - .OfType() - .Where(t => t.Type != null) - .Where(t => t.Type == name || t.Type.Contains("<" + name + ">"))) - { - // check schema - - if (cm.Parent != null && cm.Parent.Parent != null) - { - var parent = cm.Parent.Parent; - - if (parent is Table) - { - var table = (Table)parent; - - if (schema == table.Schema) - if (cm.Attributes.All(a => a.Name != text)) - cm.Attributes.Add(obsoleteAttr); - } - else if (parent is Class) - { - var cls = (Class)parent; - - bool parentClassIncludesSchemaName = cls.Name.Equals(schema + "Schema", StringComparison.InvariantCultureIgnoreCase); - bool classIsForDefaultSchema = cls.Name == DataContextName; - bool isExtensionMethod = cls.Parent is Namespace || cls.Name == "TableExtensions"; - - if (classIsForDefaultSchema || parentClassIncludesSchemaName || isExtensionMethod) - if (cm.Attributes.All(a => a.Name != text)) - cm.Attributes.Add(obsoleteAttr); - } - } - } - } - - afterGenerateLinqToDBModel(); - }; - } -#> diff --git a/Source/LinqToDB.Templates/PluralizationService.ttinclude b/Source/LinqToDB.Templates/PluralizationService.ttinclude deleted file mode 100644 index 352edfb..0000000 --- a/Source/LinqToDB.Templates/PluralizationService.ttinclude +++ /dev/null @@ -1,122 +0,0 @@ -<#@ assembly name="System.Data.Entity.Design" #> -<#@ import namespace="System.Data.Entity.Design.PluralizationServices" #> -<# - { - ToPlural = Pluralization.ToPlural; - ToSingular = Pluralization.ToSingular; - } -#> -<#+ -static class Pluralization -{ - public static string CultureInfo = "en"; - - static PluralizationService _service; - - public static Dictionary Dictionary = new Dictionary - { - { "access", "accesses" }, { "afterlife", "afterlives" }, { "alga", "algae" }, - { "alumna", "alumnae" }, { "alumnus", "alumni" }, { "analysis", "analyses" }, - { "antenna", "antennae" }, { "appendix", "appendices" }, { "axis", "axes" }, - { "bacillus", "bacilli" }, { "basis", "bases" }, { "Bedouin", "Bedouin" }, - { "cactus", "cacti" }, { "calf", "calves" }, { "cherub", "cherubim" }, - { "child", "children" }, { "cod", "cod" }, { "cookie", "cookies" }, - { "criterion", "criteria" }, { "curriculum", "curricula" }, { "data", "data" }, - { "deer", "deer" }, { "diagnosis", "diagnoses" }, { "die", "dice" }, - { "dormouse", "dormice" }, { "elf", "elves" }, { "elk", "elk" }, - { "erratum", "errata" }, { "esophagus", "esophagi" }, { "fauna", "faunae" }, - { "fish", "fish" }, { "flora", "florae" }, { "focus", "foci" }, - { "foot", "feet" }, { "formula", "formulae" }, { "fundus", "fundi" }, - { "fungus", "fungi" }, { "genie", "genii" }, { "genus", "genera" }, - { "goose", "geese" }, { "grouse", "grouse" }, { "hake", "hake" }, - { "half", "halves" }, { "headquarters", "headquarters" }, { "hippo", "hippos" }, - { "hippopotamus", "hippopotami" }, { "hoof", "hooves" }, { "housewife", "housewives" }, - { "hypothesis", "hypotheses" }, { "index", "indices" }, { "info", "info" }, - { "jackknife", "jackknives" }, - { "knife", "knives" }, { "labium", "labia" }, { "larva", "larvae" }, - { "leaf", "leaves" }, { "life", "lives" }, { "loaf", "loaves" }, - { "louse", "lice" }, { "magus", "magi" }, { "man", "men" }, - { "memorandum", "memoranda" }, { "midwife", "midwives" }, { "millennium", "millennia" }, - { "moose", "moose" }, { "mouse", "mice" }, { "nebula", "nebulae" }, - { "neurosis", "neuroses" }, { "nova", "novas" }, { "nucleus", "nuclei" }, - { "oesophagus", "oesophagi" }, { "offspring", "offspring" }, { "ovum", "ova" }, - { "ox", "oxen" }, { "papyrus", "papyri" }, { "passerby", "passersby" }, - { "penknife", "penknives" }, { "person", "people" }, { "phenomenon", "phenomena" }, - { "placenta", "placentae" }, { "pocketknife", "pocketknives" }, { "process", "processes" }, - { "pupa", "pupae" }, { "radius", "radii" }, { "reindeer", "reindeer" }, - { "retina", "retinae" }, { "rhinoceros", "rhinoceros" }, { "roe", "roe" }, - { "salmon", "salmon" }, { "scarf", "scarves" }, { "self", "selves" }, - { "seraph", "seraphim" }, { "series", "series" }, { "sheaf", "sheaves" }, - { "sheep", "sheep" }, { "shelf", "shelves" }, { "species", "species" }, - { "spectrum", "spectra" }, { "status", "status" }, { "stimulus", "stimuli" }, - { "stratum", "strata" }, { "supernova", "supernovas" }, { "swine", "swine" }, - { "terminus", "termini" }, { "thesaurus", "thesauri" }, { "thesis", "theses" }, - { "thief", "thieves" }, { "trout", "trout" }, { "vulva", "vulvae" }, - { "wife", "wives" }, { "wildebeest", "wildebeest" }, { "wolf", "wolves" }, - { "woman", "women" }, { "yen", "yen" }, - }; - - static string GetLastWord(string str) - { - if (string.IsNullOrWhiteSpace(str)) - return string.Empty; - - var i = str.Length - 1; - var isLower = char.IsLower(str[i]); - - while (i > 0 && char.IsLower(str[i-1]) == isLower) - i--; - - return str.Substring(isLower && i > 0 ? i - 1 : i); - } - - public static string ToPlural(string str) - { - if (_service == null) - _service = PluralizationService.CreateService(System.Globalization.CultureInfo.GetCultureInfo(CultureInfo)); - - var word = GetLastWord(str); - - string newWord; - - if (!Dictionary.TryGetValue(word.ToLower(), out newWord)) - newWord = _service.IsPlural(word) ? word : _service.Pluralize(word); - - if (string.Compare(word, newWord, true) != 0) - { - if (char.IsUpper(word[0])) - newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); - - return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; - } - - return str; - } - - public static string ToSingular(string str) - { - if (_service == null) - _service = PluralizationService.CreateService(System.Globalization.CultureInfo.GetCultureInfo(CultureInfo)); - - var word = GetLastWord(str); - - var newWord = - Dictionary - .Where(dic => string.Compare(dic.Value, word, true) == 0) - .Select(dic => dic.Key) - .FirstOrDefault() - ?? - (_service.IsSingular(word) ? word : _service.Singularize(word)); - - if (string.Compare(word, newWord, true) != 0) - { - if (char.IsUpper(word[0])) - newWord = char.ToUpper(newWord[0]) + newWord.Substring(1, newWord.Length - 1); - - return word == str ? newWord : str.Substring(0, str.Length - word.Length) + newWord; - } - - return str; - } -} -#> diff --git a/Source/LinqToDB.Templates/README.md b/Source/LinqToDB.Templates/README.md deleted file mode 100644 index ae9d457..0000000 --- a/Source/LinqToDB.Templates/README.md +++ /dev/null @@ -1,237 +0,0 @@ -# T4 Models - -T4 models are used to generate POCO's C# code using your database structure. - -### Build status -* Master: [![Build status](https://ci.appveyor.com/api/projects/status/ld4cv53wyfi4qtqm/branch/master?svg=true)](https://ci.appveyor.com/project/igor-tkachev/t4models/branch/master) -* Current: [![Build status](https://ci.appveyor.com/api/projects/status/ld4cv53wyfi4qtqm?svg=true)](https://ci.appveyor.com/project/igor-tkachev/t4models) - -## Installation - -Firstly you should install one of tools packages into your project: - -`Install-Package linq2db.XXX` - -Where XXX is one of supported databases, for example: - -`Install-Package linq2db.SqlServer` - -This also will install needed linq2db packages: -* linq2db.t4models -* linq2db - -But **not** data provider packages (install them only if needed to compile your project, T4 models ships it's own data provider assemblies). - -### .Net Core specific - -Because of .Net Core projects do not support NuGet content files all stuff is not copied into project's folder, so to run T4 templates you'll need: -* open `$(SolutionDir).tools\linq2db.t4models` in Explorer -* copy `CopyMe.XXX.Core.tt.txt` to your project's folder or subfolder, then you should use it instead of `CopyMe.XXX.tt.txt` - -# Running - -After package installing you will see new `LinqToDB.Templates` folder in your project, this folder contains all needed T4 stuff to generate your model. Also would be created new folder in tour solution: `$(SolutionDir).tools\linq2db.t4models`, it is used to store and link assemblies, needed for generation (linq2db.dll and data provider assemblies). - -To create a data model template take a look at one of the CopyMe.XXX.tt.txt file in your LinqToDB.Templates project folder. Copy this file to needed project location and rename it, like `MyModel.tt` - -There are few main steps in this file: -1. Configuring generation process (read below) -1. Loading metadata - this is a call to `LoadMatadata()` function - it connects to your database and fetches all needed metadata (table structure, views, and so on) -1. Customizing generation process (read below) -1. Calling `GenerateModel()` - this will run model generation - -## Configuring generation process - -Use the following initialization **before** you call the `LoadMetadata()` method. - -```c# -NamespaceName = "DataModels"; // Namespace of the generated classes. - -DataContextName = null; // DataContext class name. If null - database name + "DB". -BaseDataContextClass = null; // Base DataContext class name. If null - LinqToDB.Data.DataConnection. -GenerateConstructors = true; // Enforce generating DataContext constructors. -DefaultConfiguration = null; // Defines default configuration for default DataContext constructor. - -BaseEntityClass = null; // Base Entity class name. If null - none. -DatabaseName = null; // Table database name - [Table(Database="DatabaseName")]. -GenerateDatabaseName = false; // Always generate table database name, even though DatabaseName is null. -IncludeDefaultSchema = true; // Default schema name is generated - [Table(Database="Northwind", Schema="dbo", Name="Customers")] - -OneToManyAssociationType = "IEnumerable<{0}>"; // One To Many association type (for members only). Change it to "List<{0}>" if needed. -GenerateAssociations = true; // Enforce generating associations as type members. -GenerateBackReferences = true; // Enforce generating backreference associations (affects both members and extensions). -GenerateAssociationExtensions = false; // Enforce generating associations as extension methods. NB: this option does not affect GenerateAssociations. This will require linq2db 1.9.0 and above - -ReplaceSimilarTables = true; // Replaces stored procedure result class names with similar to existing table class names. -GenerateFindExtensions = true; // Generates find extension methods based on PKs information. -IsCompactColumns = true; // If true, column compact view. - -PluralizeClassNames = false; // If true, pluralizes table class names. -SingularizeClassNames = true; // If true, singularizes table class names. -PluralizeDataContextPropertyNames = true; // If true, pluralizes DataContext property names. -SingularizeDataContextPropertyNames = false; // If true, singularizes DataContex pProperty names. - -GenerateDataTypes = false; // If true, generates the DataType/Length/Precision/Scale properties of the Column attribute (unless overriden by the properties below). -GenerateDataTypeProperty = null; // If true, generates the DataType property of the Column attribute. If false, excludes generation on the DataType property even if GenerateDataTypes == true. -GenerateLengthProperty = null; // If true, generates the Length property of the Column attribute. If false, excludes generation on the Length property even if GenerateDataTypes == true. -GeneratePrecisionProperty = null; // If true, generates the Precision property of the Column attribute. If false, excludes generation on the Precision property even if GenerateDataTypes == true. -GenerateScaleProperty = null; // If true, generates the Scale property of the Column attribute. If false, excludes generation on the Scale property even if GenerateDataTypes == true. -GenerateDbTypes = false; // If true, generates the DbType property of the Column attribute. - -GenerateObsoleteAttributeForAliases = false; // If true, generates [Obsolete] attribute for aliases. -IsCompactColumnAliases = true; // If true, column alias compact view. - -NormalizeNames = true; // convert some_name to SomeName for types and members - -GetSchemaOptions.ExcludedSchemas = new[] { "TestUser", "SYSSTAT" }; // Defines excluded schemas. -GetSchemaOptions.IncludedSchemas = new[] { "TestUser", "SYS" }; // Defines only included schemas. - -GetSchemaOptions.ExcludedCatalogs = new[] { "TestUser", "SYSSTAT" }; // Defines excluded catalogs. -GetSchemaOptions.IncludedCatalogs = new[] { "TestUser", "SYS" }; // Defines only included catalogs. - -Func ToValidName = ToValidNameDefault; // Defines function to convert names to valid (My_Table to MyTable) -Func ConvertToCompilable = ConvertToCompilableDefault; // Converts name to c# compatible. By default removes uncompatible symbols and converts result with ToValidName - -Func GetAssociationExtensionSinglularName = GetAssociationExtensionSinglularNameDefault; // Gets singular method extension method name for association -Func GetAssociationExtensionPluralName = GetAssociationExtensionPluralNameDefault; // Gets plural method extension method name for association - -``` - -## Provider specific configurations -### SQL Server -```cs -bool GenerateSqlServerFreeText = true; // Defines wheather to generate extensions for Free Text search, or not -``` -### PostgreSQL -```cs -bool GenerateCaseSensitiveNames = false; // Defines whether to generate case sensitive or insensitive names -``` -### Sybase -```cs -bool GenerateSybaseSystemTables = false; // Defines whether to generate Sybase sysobjects tables or not -``` - -## Customizing generation process - -Use the following code to modify your model **before** you call the `GenerateModel()` method. - -```c# -GetTable("Person").TypeName = "MyName"; // Replaces table name. -GetTable("Person").BaseClass = "PersonBase, IId"; // Set base class & interface for type, null to reset - -GetColumn("Person", "PersonID") .MemberName = "ID"; // Replaces column PersonID of Person table with ID. -GetColumn("Person", "PasswordHash").SkipOnUpdate = true; // Set [Column(SkipOnUpdate=true)], same for other column options -GetColumn("Person", "Gender") .Type = "global::Model.Gender"; // Change column type - -GetFK("Orders", "FK_Orders_Customers").MemberName = "Customers"; // Replaces association name. -GetFK("Orders", "FK_Orders_Customers").AssociationType = AssociationType.OneToMany; // Changes association type. - -SetTable(string tableName, - string TypeName = null, - string DataContextPropertyName = null) - - .Column(string columnName, string MemberName = null, string Type = null, bool? IsNullable = null) - .FK (string fkName, string MemberName = null, AssociationType? AssociationType = null) - ; - -Model.Usings.Add("MyNamespace"); // Adds using of namespace. - -// Replaces all the columns where name is 'TableName' + 'ID' with 'ID'. -foreach (var t in Tables.Values) - foreach (var c in t.Columns.Values) - if (c.IsPrimaryKey && c.MemberName == t.TypeName + "ID") - c.MemberName = "ID"; -``` - -## Useful members and data structures - -```c# -Dictionary Tables = new Dictionary (); -Dictionary Procedures = new Dictionary(); - -Table GetTable (string name); -Procedure GetProcedure (string name); -Column GetColumn (string tableName, string columnName); -ForeignKey GetFK (string tableName, string fkName); -ForeignKey GetForeignKey(string tableName, string fkName); - -public class Table -{ - public string Schema; - public string TableName; - public string DataContextPropertyName; - public bool IsView; - public string Description; - public string AliasPropertyName; - public string AliasTypeName; - public string TypeName; - - public Dictionary Columns; - public Dictionary ForeignKeys; -} - -public partial class Column : Property -{ - public string ColumnName; // Column name in database - public bool IsNullable; - public bool IsIdentity; - public string ColumnType; // Type of the column in database - public DbType DbType; - public string Description; - public bool IsPrimaryKey; - public int PrimaryKeyOrder; - public bool SkipOnUpdate; - public bool SkipOnInsert; - public bool IsDuplicateOrEmpty; - public string AliasName; - public string MemberName; -} - -public enum AssociationType -{ - Auto, - OneToOne, - OneToMany, - ManyToOne, -} - -public partial class ForeignKey : Property -{ - public string KeyName; - public Table OtherTable; - public List ThisColumns; - public List OtherColumns; - public bool CanBeNull; - public ForeignKey BackReference; - public string MemberName; - public AssociationType AssociationType; -} - -public partial class Procedure : Method -{ - public string Schema; - public string ProcedureName; - public bool IsFunction; - public bool IsTableFunction; - public bool IsDefaultSchema; - - public Table ResultTable; - public Exception ResultException; - public List
SimilarTables; - public List ProcParameters; -} - -public class Parameter -{ - public string SchemaName; - public string SchemaType; - public bool IsIn; - public bool IsOut; - public bool IsResult; - public int? Size; - public string ParameterName; - public string ParameterType; - public Type SystemType; - public string DataType; -} -``` diff --git a/Source/LinqToDB.Templates/T4Model.ttinclude b/Source/LinqToDB.Templates/T4Model.ttinclude deleted file mode 100644 index 50ce91a..0000000 --- a/Source/LinqToDB.Templates/T4Model.ttinclude +++ /dev/null @@ -1,1482 +0,0 @@ -<#@ assembly name="System.Core" #> -<#@ import namespace="System" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.Linq" #> -<#+ -static Action WriteComment = (tt,s) => tt.WriteLine("//{0}", s); - -Action BeforeGenerateModel = () => {}; - -bool GenerateProcedureErrors = true; - -void GenerateModel() -{ - Model.SetTree(); - - BeforeGenerateModel(); - - if (GenerationEnvironment.Length > 0 && GenerationEnvironment.ToString().Trim().Length == 0) - GenerationEnvironment.Length = 0; - - WriteComment(this, "---------------------------------------------------------------------------------------------------"); - WriteComment(this, " "); - WriteComment(this, " This code was generated by T4Model template for T4 (https://github.com/linq2db/t4models)."); - WriteComment(this, " Changes to this file may cause incorrect behavior and will be lost if the code is regenerated."); - WriteComment(this, " "); - WriteComment(this, "---------------------------------------------------------------------------------------------------"); - - Model.Render(this); -} - -void Trim() -{ - var arr = new[] { '\r', '\n', ' ' }; - while (GenerationEnvironment.Length > 0 && arr.Contains(GenerationEnvironment[GenerationEnvironment.Length - 1])) - GenerationEnvironment.Length--; - - WriteLine(""); -} - -static Action WriteUsing = (tt,s) => tt.WriteLine("using {0};", s); - -void RenderUsings(List usings) -{ - var q = - from ns in usings.Distinct() - group ns by ns.Split('.')[0]; - - var groups = - (from ns in q where ns.Key == "System" select ns).Concat - (from ns in q where ns.Key != "System" orderby ns.Key select ns); - - foreach (var gr in groups) - { - foreach (var ns in from s in gr orderby s select s) - WriteUsing(this, ns); - - WriteLine(""); - } - - Trim(); -} - -// Base data types. -// -public interface ITree -{ - ITree Parent { get; set; } - IEnumerable GetNodes(); - void SetTree(); -} - -ModelSource Model = new ModelSource(); - -public partial class ModelSource : ITree -{ - public int CurrentNamespace = 0; - - public List Usings = new List { "System" }; - public List Namespaces = new List { new Namespace() }; - - public Namespace Namespace { get { return Namespaces[CurrentNamespace]; } } - public List Types { get { return Namespaces[CurrentNamespace].Types; } } - - public virtual void Render(GeneratedTextTransformation tt) - { - tt.RenderUsings(Usings); - tt.WriteLine(""); - - foreach (var nm in Namespaces) - { - nm.Render(tt); - tt.WriteLine(""); - } - - tt.Trim(); - } - - public ITree Parent { get; set; } - public IEnumerable GetNodes() { return Namespaces; } - - public void SetTree() - { - foreach (var ch in GetNodes()) - { - ch.Parent = this; - ch.SetTree(); - } - } -} - -static Action WriteBeginNamespace = (tt,s) => { tt.WriteLine("namespace {0}", s); tt.WriteLine("{"); }; -static Action WriteEndNamespace = tt => tt.WriteLine("}"); - -public partial class Namespace : ITree -{ - public string Name; - public List Types = new List(); - public List Usings = new List(); - - public virtual void Render(GeneratedTextTransformation tt) - { - if (!string.IsNullOrEmpty(Name)) - { - WriteBeginNamespace(tt, Name); - tt.PushIndent("\t"); - } - - tt.RenderUsings(Usings); - - foreach (var t in Types) - { - t.Render(tt); - tt.WriteLine(""); - } - - tt.Trim(); - - if (!string.IsNullOrEmpty(Name)) - { - tt.PopIndent(); - WriteEndNamespace(tt); - } - } - - public ITree Parent { get; set; } - public IEnumerable GetNodes() { return Types; } - - public void SetTree() - { - foreach (var ch in GetNodes()) - { - ch.Parent = this; - ch.SetTree(); - } - } -} - -public interface IClassMember : ITree -{ -} - -public enum AccessModifier -{ - Public, - Protected, - Internal, - Private, - Partial -} - -public abstract partial class TypeBase : IClassMember -{ - public AccessModifier AccessModifier = AccessModifier.Public; - public string Name; - public bool IsPartial = true; - public List Comment = new List(); - public List Attributes = new List(); - public string Conditional; - - public abstract void Render(GeneratedTextTransformation tt); - - protected virtual void BeginConditional(GeneratedTextTransformation tt) - { - if (Conditional != null) - { - tt.RemoveSpace(); - tt.WriteLine("#if " + Conditional); - tt.WriteLine(""); - } - } - - protected virtual void EndConditional(GeneratedTextTransformation tt) - { - if (Conditional != null) - { - tt.RemoveSpace(); - tt.WriteLine(""); - tt.RemoveSpace(); - tt.WriteLine("#endif"); - } - } - - public ITree Parent { get; set; } - public abstract IEnumerable GetNodes(); - public abstract void SetTree (); -} - -static Action WriteBeginClass = (tt,cl) => -{ - tt.Write(cl.AccessModifier.ToString().ToLower() + " "); - if (cl.IsStatic) tt.Write("static "); - if (cl.IsPartial) tt.Write("partial ", cl.Name); - tt.Write("class {0}", cl.Name); - - if (!string.IsNullOrEmpty(cl.BaseClass) || cl.Interfaces.Count > 0) - { - var arr = new[] { cl.BaseClass }.Concat(cl.Interfaces) - .Where(n => n != null) - .ToArray(); - - tt.Write(" : "); - tt.Write(string.Join(", ", arr)); - } - - tt.WriteLine(""); - tt.WriteLine("{"); -}; - -static Action WriteEndClass = tt => tt.WriteLine("}"); - -public partial class Class : TypeBase -{ - public string BaseClass; - public bool IsStatic = false; - public List Interfaces = new List(); - public List Members = new List(); - - public Class() - { - } - - public Class(string name, params IClassMember[] members) - { - Name = name; - Members.AddRange(members); - } - - public override void Render(GeneratedTextTransformation tt) - { - BeginConditional(tt); - - foreach (var c in Comment) - tt.WriteLine("//" + c); - - if (Attributes.Count > 0) - { - var aa = Attributes.Where(a => !a.IsSeparated).ToList(); - - if (aa.Count > 0) - { - tt.Write("["); - - for (var i = 0; i < aa.Count; i++) - { - if (i > 0) SkipSpacesAndInsert(tt, ", "); - aa[i].Render(tt); - } - - tt.WriteLine("]"); - } - - aa = Attributes.Where(a => a.IsSeparated).ToList(); - - foreach (var a in aa) - { - tt.Write("["); - a.Render(tt); - tt.WriteLine("]"); - } - } - - WriteBeginClass(tt, this); - tt.PushIndent("\t"); - - foreach (var cm in Members) - { - if (cm is MemberBase) - { - var m = (MemberBase)cm; - - if (!(m is MemberGroup)) - m.BeginConditional(tt, false); - - foreach (var c in m.Comment) - WriteComment(tt, c); - - if (m.Attributes.Count > 0) - { - var q = - from a in m.Attributes - group a by a.Conditional ?? ""; - - foreach (var g in q) - { - if (g.Key.Length > 0) - { - tt.RemoveSpace(); - tt.WriteLine("#if " + g.Key); - } - - var attrs = g.ToList(); - - tt.Write("["); - - for (var i = 0; i < attrs.Count; i++) - { - if (i > 0) SkipSpacesAndInsert(tt, ", "); - attrs[i].Render(tt); - } - - tt.WriteLine("]"); - - if (g.Key.Length > 0) - { - tt.RemoveSpace(); - tt.WriteLine("#endif"); - } - } - } - - m.Render(tt, false); - if (m.InsertBlankLineAfter) - tt.WriteLine(""); - - if (!(m is MemberGroup)) - m.EndConditional(tt, false); - } - else if (cm is TypeBase) - { - var t = (TypeBase)cm; - - t.Render(tt); - tt.WriteLine(""); - } - } - - tt.Trim(); - - tt.PopIndent(); - WriteEndClass(tt); - - EndConditional(tt); - } - - public override IEnumerable GetNodes() - { - return Members; - } - - public override void SetTree() - { - foreach (var ch in GetNodes()) - { - ch.Parent = this; - ch.SetTree(); - } - } -} - -public abstract partial class MemberBase : IClassMember -{ - public string ID; - public AccessModifier AccessModifier = AccessModifier.Public; - public string Name; - public string Type; - public List Comment = new List(); - public string EndLineComment; - public List Attributes = new List(); - public bool InsertBlankLineAfter = true; - public string Conditional; - - public int AccessModifierLen; - public int ModifierLen; - public int TypeLen; - public int NameLen; - public int ParamLen; - public int BodyLen; - - public virtual int CalcModifierLen() { return 0; } - public abstract int CalcBodyLen (); - public virtual int CalcParamLen () { return 0; } - public abstract void Render (GeneratedTextTransformation tt, bool isCompact); - - public virtual void BeginConditional(GeneratedTextTransformation tt, bool isCompact) - { - if (Conditional != null) - { - tt.RemoveSpace(); - tt.WriteLine("#if " + Conditional); - if (!isCompact) - tt.WriteLine(""); - } - } - - public virtual void EndConditional(GeneratedTextTransformation tt, bool isCompact) - { - if (Conditional != null) - { - tt.RemoveSpace(); - tt.WriteLine("#endif"); - if (!isCompact) - tt.WriteLine(""); - } - } - - public ITree Parent { get; set; } - public virtual IEnumerable GetNodes() { return Enumerable.Empty(); } - public virtual void SetTree () {} -} - -static Action BeginRegion = (tt,s) => { tt.WriteLine("#region {0}", s); }; -static Action EndRegion = (tt) => { tt.WriteLine("#endregion"); }; - -public partial class MemberGroup : MemberBase -{ - public string Region; - public bool IsCompact; - public bool IsPropertyGroup; - public List Members = new List(); - public List Errors = new List(); - - public override int CalcBodyLen() { return 0; } - - public override void Render(GeneratedTextTransformation tt, bool isCompact) - { - if (!string.IsNullOrEmpty(Region)) - { - BeginRegion(tt, Region); - tt.WriteLine(""); - } - - BeginConditional(tt, isCompact); - - if (Errors.Count > 0 && tt.GenerateProcedureErrors) - { - tt.RemoveSpace(); - WriteComment(tt, " Use 'GenerateProcedureErrors=false' to disable errors."); - foreach (var error in Errors) - { - tt.Error(error); - - foreach (var e in error.Split('\n')) - { - tt.RemoveSpace(); - tt.WriteLine("#error " + e.Trim('\r')); - } - } - - tt.WriteLine(""); - } - - if (IsCompact) - { - var allMembers = GetTreeNodes(this).OfType().Where(m => !(m is MemberGroup)).ToList(); - - if (allMembers.Count > 0) - { - int max = allMembers.Max(m => m.AccessModifier.ToString().Length); - foreach (var m in allMembers) - m.AccessModifierLen = max; - - max = allMembers.Max(m => m.CalcModifierLen()); - foreach (var m in allMembers) - m.ModifierLen = max; - - max = allMembers.Max(m => (m.Type ?? "").Length); - foreach (var m in allMembers) - m.TypeLen = max; - - var notHasGetter = allMembers.OfType().Any(m => m.IsAuto && !m.HasGetter); - var notHasSetter = allMembers.OfType().Any(m => m.IsAuto && !m.HasSetter); - - foreach (var p in allMembers.OfType()) - { - if (notHasGetter) p.GetterLen = 13; - if (notHasSetter) p.SetterLen = 13; - } - - max = allMembers.Max(m => m.Name.Length); - foreach (var m in allMembers) - m.NameLen = max; - - max = allMembers.Max(m => m.CalcParamLen()); - foreach (var m in allMembers) - m.ParamLen = max; - - max = allMembers.Max(m => m.CalcBodyLen()); - foreach (var m in allMembers) - m.BodyLen = max; - - var members = - ( - from m in allMembers - select new - { - m, - attrs = - ( - from a in m.Attributes - group a by a.Name into gr - select gr.Select((a,i) => new { a, name = a.Name + "." + i }).ToList() into s - from a in s - select a - ).ToList() - } - ).ToList(); - - var attrWeight = - ( - from m in members - from a in m.attrs - group a by a.name into gr - select new { gr.Key, Count = gr.Count() } - ).ToDictionary(a => a.Key, a => a.Count); - - var q = - from m in members - where m.attrs.Count > 0 - select new { m, w = m.attrs.Sum(aa => attrWeight[aa.name]) } into m - orderby m.w descending - select m.m; - - var attrs = new List(); - - foreach (var m in q) - { - var list = m.attrs.Select(a => a.name).ToList(); - - if (attrs.Count == 0) - attrs.AddRange(list); - else - { - for (var i = 0; i < list.Count; i++) - { - var nm = list[i]; - - if (!attrs.Contains(nm)) - { - for (var j = i + 1; j < list.Count; j++) - { - var idx = attrs.IndexOf(list[j]); - - if (idx >= 0) - { - attrs.Insert(idx, nm); - break; - } - } - } - - if (!attrs.Contains(nm)) - attrs.Add(nm); - } - } - } - - var mms = members.Select(m => - { - var arr = new Attribute[attrs.Count]; - - foreach (var a in m.attrs) - arr[attrs.IndexOf(a.name)] = a.a; - - return new { m.m, attrs = arr.ToList() }; - }).ToList(); - - var idxs = Enumerable.Range(0, attrs.Count).Select(_ => new List()).ToList(); - - for (var i = 0; i < mms.Count; i++) - for (var j = 0; j < mms[i].attrs.Count; j++) - if (mms[i].attrs[j] != null) - idxs[j].Add(i); - - var toRemove = new List(); - - for (int i = 1; i < idxs.Count; i++) - { - for (int j = 0; j < i; j++) - { - if (idxs[j] == null) - continue; - - if (idxs[i].Intersect(idxs[j]).Count() == 0) - { - foreach (var m in mms) - { - if (m.attrs[i] != null) - { - m.attrs[j] = m.attrs[i]; - m.attrs[i] = null; - } - } - - idxs[j].AddRange(idxs[i]); - idxs[i] = null; - toRemove.Add(i); - break; - } - } - - } - - foreach (var n in toRemove.OrderByDescending(i => i)) - foreach (var m in mms) - m.attrs.RemoveAt(n); - - var lens = new int[attrs.Count - toRemove.Count]; - - foreach (var m in mms) - { - for (var i = 0; i < m.attrs.Count; i++) - { - var a = m.attrs[i]; - - if (a != null) - { - var len = a.Name.Length; - - if (a.Parameters.Count >= 0) - len += a.Parameters.Sum(p => 2 + p.Length); - - lens[i] = Math.Max(lens[i], len); - } - } - } - - foreach (var m in allMembers) - { - if (!(m is MemberGroup)) - m.BeginConditional(tt, IsCompact); - - foreach (var c in m.Comment) - WriteComment(tt, c); - - if (attrs.Count > 0) - { - var ma = mms.First(mr => mr.m == m); - - if (m.Attributes.Count > 0) - { - tt.Write("["); - - for (var i = 0; i < ma.attrs.Count; i++) - { - var a = ma.attrs[i]; - - if (a == null) - { - tt.WriteSpaces(lens[i]); - if (i + 1 < ma.attrs.Count) - tt.Write(" "); - } - else - { - var len = tt.GenerationEnvironment.Length; - a.Render(tt); - len = (tt.GenerationEnvironment.Length - len); - - var commaAdded = false; - - for (var j = i + 1; j < ma.attrs.Count; j++) - { - if (ma.attrs[j] != null) - { - SkipSpacesAndInsert(tt, ", "); - commaAdded = true; - break; - } - } - - if (i + 1 < ma.attrs.Count && !commaAdded) - tt.Write(" "); - - tt.WriteSpaces(lens[i] - len); - } - } - - tt.Write("] "); - } - else - { - tt.WriteSpaces(lens.Sum() + ma.attrs.Count * 2 + 1); - } - } - - m.Render(tt, true); - - if (!IsCompact) - tt.WriteLine(""); - - if (!(m is MemberGroup)) - m.EndConditional(tt, IsCompact); - } - } - } - else - { - foreach (var cm in Members) - { - if (cm is MemberBase) - { - var m = (MemberBase)cm; - - if (!(m is MemberGroup)) - m.BeginConditional(tt, IsCompact); - - foreach (var c in m.Comment) - WriteComment(tt, c); - - if (m.Attributes.Count > 0) - { - var q = - from a in m.Attributes - group a by a.Conditional ?? ""; - - foreach (var g in q) - { - if (g.Key.Length > 0) - { - tt.RemoveSpace(); - tt.WriteLine("#if " + g.Key); - } - - var attrs = g.ToList(); - - var aa = attrs.Where(a => !a.IsSeparated).ToList(); - - if (aa.Count > 0) - { - tt.Write("["); - - for (var i = 0; i < aa.Count; i++) - { - if (i > 0) tt.Write(", "); - aa[i].Render(tt); - } - - tt.WriteLine("]"); - } - - aa = attrs.Where(a => a.IsSeparated).ToList(); - - foreach (var a in aa) - { - tt.Write("["); - a.Render(tt); - tt.WriteLine("]"); - } - - if (g.Key.Length > 0) - { - tt.RemoveSpace(); - tt.WriteLine("#endif"); - } - } - } - - m.Render(tt, false); - - if (m.InsertBlankLineAfter) - tt.WriteLine(""); - - if (!(m is MemberGroup)) - m.EndConditional(tt, IsCompact); - } - else if (cm is TypeBase) - { - var t = (TypeBase)cm; - - t.Render(tt); - tt.WriteLine(""); - } - } - } - - tt.Trim(); - - EndConditional(tt, isCompact); - - if (!string.IsNullOrEmpty(Region)) - { - tt.WriteLine(""); - EndRegion(tt); - } - } - - public override IEnumerable GetNodes() { return Members; } - - public override void SetTree() - { - foreach (var ch in GetNodes()) - { - ch.Parent = this; - ch.SetTree(); - } - } -} - -static Action WriteField = (tt,f) => -{ - var am = f.AccessModifier.ToString().ToLower(); - var mdf = - (f.IsStatic ? " static" : "") + - (f.IsReadonly ? " readonly" : "") ; - - tt.Write("{0}{1}{2}{3} {4}{5} {6}", - am, LenDiff(f.AccessModifierLen, am), - mdf, LenDiff(f.ModifierLen, mdf), - f.Type, LenDiff(f.TypeLen, f.Type), - f.Name); - - if (f.InitValue != null) - { - tt.Write(" = {0}", f.InitValue); - } - - tt.Write(";"); - - if (!string.IsNullOrEmpty(f.EndLineComment)) - { - tt.WriteSpaces(f.NameLen - f.Name.Length + f.BodyLen + f.ParamLen - 1); - tt.Write(" "); - WriteComment(tt, " " + f.EndLineComment); - } - else - tt.WriteLine(""); -}; - -public partial class Field : MemberBase -{ - public bool IsStatic; - public bool IsReadonly; - public string InitValue; - - public Field() - { - } - - public Field(string type, string name) - { - Type = type; - Name = name; - } - - public override int CalcModifierLen() - { - return - (IsStatic ? " static". Length : 0) + - (IsReadonly ? " readonly".Length : 0) ; - } - - public override int CalcBodyLen() { return InitValue == null ? 1 : 4 + InitValue.Length; } - - public override void Render(GeneratedTextTransformation tt, bool isCompact) - { - WriteField(tt, this); - } -} - -static Action WriteEvent = (tt,m) => -{ - var am = m.AccessModifier.ToString().ToLower(); - var mdf = - (m.IsStatic ? " static" : "") + - (m.IsVirtual ? " virtual" : "") + - " event"; - - tt.Write("{0}{1}{2}{3} {4}{5} {6};", - am, LenDiff(m.AccessModifierLen, am), - mdf, LenDiff(m.ModifierLen, mdf), - m.Type, LenDiff(m.TypeLen, m.Type), - m.Name); - - if (!string.IsNullOrEmpty(m.EndLineComment)) - { - tt.WriteSpaces(m.NameLen - m.Name.Length + m.BodyLen + m.ParamLen - 1); - tt.Write(" "); - WriteComment(tt, " " + m.EndLineComment); - } - else - tt.WriteLine(""); -}; - -public partial class Event : MemberBase -{ - public bool IsStatic; - public bool IsVirtual; - - public Event() - { - } - - public Event(string type, string name) - { - Type = type; - Name = name; - } - - public override int CalcModifierLen() - { - return - (IsStatic ? " static". Length : 0) + - (IsVirtual ? " virtual".Length : 0) + - " event".Length; - } - - public override int CalcBodyLen() { return 1; } - - public override void Render(GeneratedTextTransformation tt, bool isCompact) - { - WriteEvent(tt, this); - } -} - -static Action WriteProperty = (tt,p,compact) => -{ - var am = p.AccessModifier.ToString().ToLower(); -// var mdf = p.IsVirtual ? " virtual" : ""; - var mdf = p.IsAbstract ? " abstract" : p.IsVirtual ? " virtual" : p.IsOverride ? " override" : p.IsStatic ? " static" : ""; - - tt.Write("{0}{1}{2}{3} {4}{5} {6}", - am, LenDiff(p.AccessModifierLen, am), - mdf, LenDiff(p.ModifierLen, mdf), - p.Type, LenDiff(p.TypeLen, p.Type), - p.Name); - - Action writeComment = () => - { - if (!string.IsNullOrEmpty(p.EndLineComment)) - { - tt.Write(" "); - WriteComment(tt, " " + p.EndLineComment); - } - else - tt.WriteLine(""); - }; - - if (p.IsAuto) - { - tt.Write(LenDiff(p.NameLen + p.ParamLen, p.Name)); - - var len = tt.GenerationEnvironment.Length; - - tt.Write(" { "); - - if (!p.HasGetter) - tt.Write("private "); - else if (p.GetterLen == 13) - tt.Write(" "); - tt.Write("get; "); - - if (!p.HasSetter) - tt.Write("private "); - else if (p.SetterLen == 13) - tt.Write(" "); - tt.Write("set; "); - - tt.Write("}"); - - if (!string.IsNullOrEmpty(p.EndLineComment)) - tt.WriteSpaces(p.BodyLen - (tt.GenerationEnvironment.Length - len)); - writeComment(); - } - else - { - if (compact) - { - tt.Write(LenDiff(p.NameLen + p.ParamLen, p.Name)); - - var len = tt.GenerationEnvironment.Length; - - tt.Write(" { "); - - if (p.HasGetter) - { - tt.Write("get { "); - foreach (var t in p.GetBody) - tt.Write("{0} ", t); - tt.Write("} "); - } - - if (p.HasSetter) - { - tt.Write("set { "); - foreach (var t in p.SetBody) - tt.Write("{0} ", t); - tt.Write("} "); - } - - tt.Write("}"); - - if (!string.IsNullOrEmpty(p.EndLineComment)) - tt.WriteSpaces(p.BodyLen - (tt.GenerationEnvironment.Length - len)); - writeComment(); - } - else - { - writeComment(); - - tt.WriteLine("{"); - tt.PushIndent("\t"); - - if (p.HasGetter) - { - if (p.GetBody.Count == 1) - { - tt.WriteLine("get {{ {0} }}", p.GetBody[0]); - } - else - { - tt.WriteLine("get"); - tt.WriteLine("{"); - tt.PushIndent("\t"); - - foreach (var t in p.GetBody) - tt.WriteLine(t); - - tt.PopIndent(); - tt.WriteLine("}"); - } - } - - if (p.HasSetter) - { - if (p.SetBody.Count == 1) - { - tt.WriteLine("set {{ {0} }}", p.SetBody[0]); - } - else - { - tt.WriteLine("set"); - tt.WriteLine("{"); - tt.PushIndent("\t"); - - foreach (var t in p.SetBody) - tt.WriteLine(t); - - tt.PopIndent(); - tt.WriteLine("}"); - } - } - - tt.PopIndent(); - tt.WriteLine("}"); - } - } -}; - -public partial class Property : MemberBase -{ - public bool IsAuto = true; - public string InitValue; - public bool IsVirtual; - public bool IsOverride; - public bool IsAbstract; - public bool IsStatic; - public bool HasGetter = true; - public bool HasSetter = true; - public List GetBody = new List(); - public List SetBody = new List(); - - public int GetterLen = 5; - public int SetterLen = 5; - - public Property() - { - } - - public Property(string type, string name, IEnumerable getBody = null, IEnumerable setBody = null) - { - Type = type; - Name = name; - - InitBody(getBody, setBody); - } - - public override int CalcModifierLen() - { - return IsVirtual ? " virtual".Length : 0; - } - - public override int CalcBodyLen() - { - if (IsAuto) - return 4 + GetterLen + SetterLen; // ' { get; set; }' - - var len = " {".Length; - - if (HasGetter) - { - len += " get {".Length; - foreach (var t in GetBody) - len += 1 + t.Length; - len += " }".Length; - } - - if (HasSetter) - { - len += " set {".Length; - foreach (var t in SetBody) - len += 1 + t.Length; - len += " }".Length; - } - - len += " }".Length; - - return len; - } - - public override void Render(GeneratedTextTransformation tt, bool isCompact) - { - if (!IsAuto && HasGetter && GetBody.Count == 1) - { - var t = GetBody[GetBody.Count - 1]; - - if (!t.StartsWith("return")) - { - t = "return " + t; - - if (!t.EndsWith(";")) - t += ";"; - - GetBody[GetBody.Count - 1] = t; - } - } - - WriteProperty(tt, this, isCompact); - } - - public Property InitBody(IEnumerable getBody = null, IEnumerable setBody = null) - { - IsAuto = getBody == null && setBody == null; - - if (getBody != null) GetBody.AddRange(getBody); - if (setBody != null) SetBody.AddRange(setBody); - - if (!IsAuto) - { - HasGetter = getBody != null; - HasSetter = setBody != null; - } - - return this; - } - - public Property InitGetter(params string[] getBody) - { - return InitBody(getBody, null); - } -} - -static Action WriteMethod = (tt,m,compact) => -{ - var am1 = m.AccessModifier.ToString().ToLower(); - var len1 = m.AccessModifierLen; - var am2 = ""; - var len2 = 0; - var mdf = m.IsAbstract ? " abstract" : m.IsVirtual ? " virtual" : m.IsOverride ? " override" : m.IsStatic ? " static" : ""; - var mlen = m.ModifierLen; - - if (am1 == "partial" && mdf.Length > 0) - { - am2 = " " + am1; len2 = len1 + 1; - am1 = ""; len1 = 0; - mdf = mdf.Trim(); - mlen--; - } - - tt.Write("{0}{1}{2}{3}{4}{5}{6}{7}{8} {9}", - am1, LenDiff(len1, am1), - mdf, LenDiff(mlen, mdf), - am2, LenDiff(len2, am2), - m.Type == null ? "" : " ", - m.Type, LenDiff(m.TypeLen, m.Type ?? ""), - m.Name); - - Action writeComment = () => - { - if (!string.IsNullOrEmpty(m.EndLineComment)) - { - tt.Write(" "); - WriteComment(tt, " " + m.EndLineComment); - } - else - tt.WriteLine(""); - }; - - Action writeParams = () => - { - tt.Write("("); - - for (int i = 0; i < m.Parameters.Count; i++) - { - if (i > 0) - tt.Write(", "); - tt.Write(m.Parameters[i]); - } - - tt.Write(")"); - }; - - if (compact) - { - tt.Write(LenDiff(m.NameLen, m.Name)); - - var len = tt.GenerationEnvironment.Length; - - writeParams(); - - foreach (var s in m.AfterSignature) - { - tt.Write(" "); - tt.Write(s); - } - - len = tt.GenerationEnvironment.Length - len; - - if (m.IsAbstract || m.AccessModifier == AccessModifier.Partial) - { - tt.Write(";"); - len = 0; - } - else - { - tt.WriteSpaces(m.ParamLen - len); - - len = tt.GenerationEnvironment.Length; - - tt.Write(" {"); - - foreach (var t in m.Body) - tt.Write(" {0}", t); - - tt.Write(" }"); - } - - if (!string.IsNullOrEmpty(m.EndLineComment)) - tt.WriteSpaces(m.BodyLen - (tt.GenerationEnvironment.Length - len)); - writeComment(); - } - else - { - writeParams (); - writeComment(); - - tt.PushIndent("\t"); - foreach (var s in m.AfterSignature) - tt.WriteLine(s); - tt.PopIndent(); - - tt.WriteLine("{"); - tt.PushIndent("\t"); - - foreach (var t in m.Body) - { - if (t.Length > 1 && t[0] == '#') - { - tt.RemoveSpace(); - } - - tt.WriteLine(t); - } - - tt.PopIndent(); - tt.WriteLine("}"); - } -}; - -public partial class Method : MemberBase -{ - public bool IsAbstract; - public bool IsVirtual; - public bool IsOverride; - public bool IsStatic; - public List AfterSignature = new List(); - public List Parameters = new List(); - public List Body = new List(); - - public Method() - { - } - - public Method(string type, string name, IEnumerable parameters = null, IEnumerable body = null) - { - Type = type; - Name = name; - - if (parameters != null) Parameters.AddRange(parameters); - if (body != null) Body. AddRange(body); - } - - public override int CalcModifierLen() - { - return - IsAbstract ? " abstract".Length : - IsVirtual ? " virtual".Length : - IsStatic ? " static".Length : 0; - } - - public override int CalcBodyLen() - { - if (IsAbstract || AccessModifier == AccessModifier.Partial) - return 1; - - var len = " {".Length; - - foreach (var t in Body) - len += 1 + t.Length; - - len += " }".Length; - - return len; - } - - public override int CalcParamLen() - { - return Parameters.Sum(p => p.Length + 2); - } - - public override void Render(GeneratedTextTransformation tt, bool isCompact) - { - WriteMethod(tt, this, isCompact); - } -} - -static Action WriteAttribute = (tt,a) => -{ - tt.Write(a.Name); - - if (a.Parameters.Count > 0) - { - tt.Write("("); - - for (var i = 0; i < a.Parameters.Count; i++) - { - if (i > 0) - if (a.Parameters[i - 1].All(c => c == ' ')) - tt.Write(" "); - else - SkipSpacesAndInsert(tt, ", "); - tt.Write(a.Parameters[i]); - } - - SkipSpacesAndInsert(tt, ")"); - } -}; - -public partial class Attribute -{ - public string Name; - public List Parameters = new List(); - public string Conditional; - public bool IsSeparated; - - public Attribute() - { - } - - public Attribute(string name, params string[] ps) - { - Name = name; - Parameters.AddRange(ps); - } - - public virtual void Render(GeneratedTextTransformation tt) - { - WriteAttribute(tt, this); - } -} - -// Helpers. -// - -Func ToPlural = s => s + "s"; -Func ToSingular = s => s; - -static string LenDiff(int max, string str) -{ - var s = ""; - - while (max-- > str.Length) - s += " "; - - return s; -} - -public void WriteSpaces(int len) -{ - while (len-- > 0) - Write(" "); -} - -void RemoveSpace() -{ - Write(" "); - - while (GenerationEnvironment.Length > 0 && - (GenerationEnvironment[GenerationEnvironment.Length - 1] == ' ' || - GenerationEnvironment[GenerationEnvironment.Length - 1] == '\t')) - GenerationEnvironment.Length--; -} - -public static IEnumerable GetTreeNodes(ITree parent) -{ - foreach (var node in parent.GetNodes()) - { - yield return node; - - foreach (var grandNode in GetTreeNodes(node)) - yield return grandNode; - } -} - -public static ITree FindNode(ITree parent, Func func) -{ - foreach (var node in parent.GetNodes()) - { - if (func(node)) - return node; - - var n = FindNode(node, func); - - if (n != null) - return n; - } - - return null; -} - -static void SkipSpacesAndInsert(GeneratedTextTransformation tt, string value) -{ - var l = tt.GenerationEnvironment.Length; - - for (; l > 0 && tt.GenerationEnvironment[l - 1] == ' '; l--) - { - } - - tt.GenerationEnvironment.Insert(l, value); -} - - -string ToCamelCase(string name) -{ - var n = 0; - - foreach (var c in name) - { - if (char.IsUpper(c)) - n++; - else - break; - } - - if (n == 0) - return name; - - if (n == name.Length) - return name.ToLower(); - - n = Math.Max(1, n - 1); - - return name.Substring(0, n).ToLower() + name.Substring(n); -} - -event Action SetPropertyValueAction; - -void SetPropertyValue(Property propertyObject, string propertyName, object value) -{ - if (SetPropertyValueAction != null) - SetPropertyValueAction(propertyObject, propertyName, value); -} -#> diff --git a/Source/LinqToDB.Templates/Validation.ttinclude b/Source/LinqToDB.Templates/Validation.ttinclude deleted file mode 100644 index a31a6c8..0000000 --- a/Source/LinqToDB.Templates/Validation.ttinclude +++ /dev/null @@ -1,175 +0,0 @@ -<# - { - var beforeGenerateModel = BeforeGenerateModel; - BeforeGenerateModel = () => - { - beforeGenerateModel(); - ValidationImpl(); - }; - } -#> -<#+ -void ValidationImpl() -{ - foreach (Class cl in GetTreeNodes(Model).OfType()) - { - var validationGroup = new MemberGroup - { - Region = "Validation", - }; - - var props = GetTreeNodes(cl).OfType().Where(p => p.CustomValidation).ToList(); - - if (props.Count > 0) - { - if (!Model.Usings.Contains("System.Collections.Generic")) - Model.Usings.Add("System.Collections.Generic"); - - var isValid = new Method("bool", "IsValid", new[] { cl.Name + " obj" }) { IsStatic = true }; - var validator = new Class("CustomValidator", isValid) { IsStatic = true, }; - var partialGroup = new MemberGroup { IsCompact = true }; - - validationGroup.Members.Add(new Field("int", "_isValidCounter") { Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } }); - validationGroup.Members.Add(validator); - validationGroup.Members.Add(partialGroup); - - isValid.Body.Add("try"); - isValid.Body.Add("{"); - isValid.Body.Add("\tobj._isValidCounter++;"); - isValid.Body.Add(""); - - var ret = "\treturn "; - - for (var i = 0; i < props.Count; i++) - { - var p = props[i]; - - var name = p.Name.Trim(); - var mname = "Validate" + name; - - cl.Attributes.Add( - new Attribute("CustomValidation", - "typeof(" + cl.Name + ".CustomValidator)", - "\"" + mname + "\"") - { - IsSeparated = true - }); - - isValid.Body.Add( - "\tvar flag" + i + " = ValidationResult.Success == " + mname + "(obj, obj." + name + ");"); - - ret += (i == 0 ? "" : " || ") + "flag" + i; - - var validate = new Method("ValidationResult", mname, - new[] { cl.Name + " obj", p.Type.Trim() + " value" }) { IsStatic = true }; - - validate.Body.Add("var list = new List();"); - validate.Body.Add(""); - validate.Body.Add("Validator.TryValidateProperty("); - validate.Body.Add("\tvalue,"); - validate.Body.Add("\tnew ValidationContext(obj, null, null) { MemberName = NameOf" + name + " }, list);"); - validate.Body.Add(""); - validate.Body.Add("obj." + mname + "(value, list);"); - validate.Body.Add(""); - validate.Body.Add("if (list.Count > 0)"); - validate.Body.Add("{"); - validate.Body.Add("\tforeach (var result in list)"); - validate.Body.Add("\t\tforeach (var name in result.MemberNames)"); - validate.Body.Add("\t\t\tobj.AddError(name, result.ErrorMessage);"); - validate.Body.Add(""); - validate.Body.Add("\treturn list[0];"); - validate.Body.Add("}"); - validate.Body.Add(""); - validate.Body.Add("obj.RemoveError(NameOf" + name + ");"); - validate.Body.Add(""); - validate.Body.Add("return ValidationResult.Success;"); - - validator.Members.Add(validate); - - partialGroup.Members.Add(new Method( - "void", - mname, - new[] - { - p.Type.Trim() + " value", - "List validationResults", - }) - { - AccessModifier = AccessModifier.Partial, - }); - } - - isValid.Body.Add(""); - isValid.Body.Add(ret + ";"); - isValid.Body.Add("}"); - isValid.Body.Add("finally"); - isValid.Body.Add("{"); - isValid.Body.Add("\tobj._isValidCounter--;"); - isValid.Body.Add("}"); - } - - props = GetTreeNodes(cl).OfType().Where(p => p.ValidateProperty && p.HasSetter).ToList(); - - if (props.Count > 0) - { - foreach (var p in props) - { - if (p.SetBody.Count > 0) - p.SetBody.Insert(0, ""); - - p.SetBody.Insert(0, "if (_validationLockCounter == 0)"); - p.SetBody.Insert(1, "{"); - - if (p.CustomValidation) - { - p.SetBody.Insert(2, "\tvar validationResult = CustomValidator.Validate" + p.Name.Trim() + "(this, value);"); - p.SetBody.Insert(3, "\tif (validationResult != ValidationResult.Success)"); - p.SetBody.Insert(4, "\t\tthrow new ValidationException(validationResult, null, null);"); - p.SetBody.Insert(5, "}"); - } - else - { - p.SetBody.Insert(2, "\tValidator.ValidateProperty("); - p.SetBody.Insert(3, "\t\tvalue,"); - p.SetBody.Insert(4, string.Format("\t\tnew ValidationContext(this, null, null) {{ MemberName = NameOf{0} }});", p.Name.Trim())); - p.SetBody.Insert(5, "}"); - } - } - - validationGroup.Members.Add(new Field("int", "_validationLockCounter") - { - AccessModifier = AccessModifier.Private, - InitValue = "0", - Attributes = { new Attribute("field : NonSerialized") { Conditional = "!SILVERLIGHT" } } - }); - - validationGroup.Members.Add(new Method ("void", "LockValidation", null, new[] { "_validationLockCounter++;" })); - validationGroup.Members.Add(new Method ("void", "UnlockValidation", null, new[] { "_validationLockCounter--;" })); - } - - if (validationGroup.Members.Count > 0) - { - if (!Model.Usings.Contains("System.ComponentModel.DataAnnotations")) - Model.Usings.Add("System.ComponentModel.DataAnnotations"); - - cl.Members.Add(validationGroup); - cl.SetTree(); - } - } -} - -partial class Property -{ - public bool CustomValidation; - public bool ValidateProperty; - - public bool Validate - { - set - { - CustomValidation = value; - ValidateProperty = value; - } - } -} -#> diff --git a/Source/ProviderHelper.cs b/Source/ProviderHelper.cs index 70c52c5..2200658 100644 --- a/Source/ProviderHelper.cs +++ b/Source/ProviderHelper.cs @@ -64,7 +64,7 @@ static void InitializeDataProviders() ProviderLibraries = "Microsoft.SqlServer.Types.dll" }); - AddDataProvider(new DynamicProviderRecord(DB2iSeriesProviderName.DB2, "DB2 iSeries", "IBM.Data.DB2.iSeries.iDB2Connection") + AddDataProvider(new DynamicProviderRecord(DB2iSeriesProviderName.DB2, "DB2 iSeries (Requires iAccess 7.1 .NET Provider)", "IBM.Data.DB2.iSeries.iDB2Connection") { InitalizationClassName = "LinqToDB.DataProvider.DB2iSeries.DB2iSeriesTools, LinqToDB.DataProvider.DB2iSeries", ProviderLibraries = "LinqToDB.DataProvider.DB2iSeries.dll;IBM.Data.DB2.iSeries.dll" diff --git a/Source/SchemaAndCodeGenerator.cs b/Source/SchemaAndCodeGenerator.cs index e968eac..ffac7b4 100644 --- a/Source/SchemaAndCodeGenerator.cs +++ b/Source/SchemaAndCodeGenerator.cs @@ -47,21 +47,10 @@ public SchemaAndCodeGenerator(IConnectionInfo cxInfo) private HashSet _existingMemberNames = new HashSet(StringComparer.InvariantCulture); - private static HashSet _keyWords = new HashSet - { - "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 GetItemsAndCode(string nameSpace, string typeName) { + typeName = ConvertToCompilable(typeName, false); + var connectionString = _cxInfo.DatabaseInfo.CustomCxString; var provider = ProviderHelper.GetProvider(ProviderName).GetDataProvider(connectionString); @@ -100,6 +89,7 @@ public IEnumerable GetItemsAndCode(string nameSpace, string typeNa .AppendLine("using System.Collections.Generic;") .AppendLine("using System.Data;") .AppendLine("using System.Reflection;") + .AppendLine("using System.Linq;") .AppendLine("using LinqToDB;") .AppendLine("using LinqToDB.Common;") .AppendLine("using LinqToDB.Data;") @@ -126,15 +116,15 @@ public IEnumerable GetItemsAndCode(string nameSpace, string typeNa Code .AppendLine($"namespace {nameSpace}") .AppendLine( "{") - .AppendLine($" public class @{typeName} : LinqToDB.LINQPad.LINQPadDataConnection") + .AppendLine($" public class {typeName} : LinqToDB.LINQPad.LINQPadDataConnection") .AppendLine( " {") - .AppendLine($" public @{typeName}(string provider, string connectionString)") + .AppendLine($" public {typeName}(string provider, string connectionString)") .AppendLine( " : base(provider, connectionString)") .AppendLine( " {") .AppendLine($" CommandTimeout = {CommandTimeout};") .AppendLine( " }") - .AppendLine($" public @{typeName}()") - .AppendLine($" : base({ToCodeString(ProviderName)}, {ToCodeString(connectionString)})") + .AppendLine($" public {typeName}()") + .AppendLine($" : base({CSharpTools.ToStringLiteral(ProviderName)}, {CSharpTools.ToStringLiteral(connectionString)})") .AppendLine( " {") .AppendLine($" CommandTimeout = {CommandTimeout};") .AppendLine( " }") @@ -228,14 +218,14 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName) { code.AppendLine(); - var spName = $"\"{sprocSqlName.Replace("\"", "\\\"")}\""; + var spName = CSharpTools.ToStringLiteral(sprocSqlName); if (p.IsTableFunction) { - code.Append($" [Sql.TableFunction(Name=\"{p.ProcedureName.Replace("\"", "\\\"")}\""); + code.Append($" [Sql.TableFunction(Name={CSharpTools.ToStringLiteral(p.ProcedureName)}"); if (p.SchemaName != null) - code.Append($", Schema=\"{p.SchemaName}\")"); + code.Append($", Schema={CSharpTools.ToStringLiteral(p.SchemaName)})"); code .AppendLine("]") @@ -307,10 +297,11 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName) } else { - var inputParameters = p.Parameters.Where(pp => pp.IsIn). ToList(); - var outputParameters = p.Parameters.Where(pp => pp.IsOut).ToList(); + 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(); - spName += inputParameters.Count == 0 ? ");" : ","; + spName += inOrOutputParameters.Count == 0 ? ");" : ","; var retName = "__ret__"; var retNo = 0; @@ -364,11 +355,17 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName) } } - for (var i = 0; i < inputParameters.Count; i++) + for (var i = 0; i < inOrOutputParameters.Count; i++) { - var pr = inputParameters[i]; + var pr = inOrOutputParameters[i]; - var str = $" new DataParameter(\"{pr.SchemaName}\", {pr.ParameterName}, DataType.{pr.DataType})"; + var str = string.Format( + !pr.IsIn && pr.IsOut + ? " new DataParameter({0}, null, DataType.{2})" + : " new DataParameter({0}, {1}, DataType.{2})", + CSharpTools.ToStringLiteral(pr.SchemaName), + pr.ParameterName, + pr.DataType); if (pr.IsOut) { @@ -380,7 +377,9 @@ void CodeProcedure(StringBuilder code, ProcedureSchema p, string sprocSqlName) str += " }"; } - str += i + 1 == inputParameters.Count ? ");" : ","; + // we need to call ToList(), because otherwise output parameters will not be updated + // with values. See https://msdn.microsoft.com/en-us/library/ms971497#gazoutas_topic6 + str += i + 1 == inOrOutputParameters.Count ? (outputParameters.Count > 0 && p.ResultTable != null ? ").ToList();" : ");") : ","; code.AppendLine(str); } @@ -495,23 +494,23 @@ void CodeTable(StringBuilder classCode, TableSchema table, bool addTableAttribut if (addTableAttribute) { - classCode.Append($" [Table(Name=\"{table.TableName}\""); + classCode.Append($" [Table(Name={CSharpTools.ToStringLiteral(table.TableName)}"); if (table.SchemaName.NotNullNorEmpty()) - classCode.Append($", Schema=\"{table.SchemaName}\""); + classCode.Append($", Schema={CSharpTools.ToStringLiteral(table.SchemaName)}"); classCode.AppendLine(")]"); } classCode - .AppendLine($" public class @{table.TypeName}") + .AppendLine($" public class {table.TypeName}") .AppendLine( " {") ; foreach (var c in table.Columns) { classCode - .Append($" [Column(\"{c.ColumnName}\"), ") + .Append($" [Column({CSharpTools.ToStringLiteral(c.ColumnName)}), ") .Append(c.IsNullable ? "Nullable" : "NotNull"); if (c.IsPrimaryKey) classCode.Append($", PrimaryKey({c.PrimaryKeyOrder})"); @@ -521,24 +520,24 @@ void CodeTable(StringBuilder classCode, TableSchema table, bool addTableAttribut var memberType = UseProviderSpecificTypes ? (c.ProviderSpecificType ?? c.MemberType) : c.MemberType; - classCode.AppendLine($" public {memberType} @{c.MemberName} {{ get; set; }}"); + classCode.AppendLine($" public {memberType} {c.MemberName} {{ get; set; }}"); } foreach (var key in table.ForeignKeys) { classCode .Append( " [Association(") - .Append($"ThisKey=\"{(key.ThisColumns.Select(c => c.MemberName)).Join(", ")}\"") - .Append($", OtherKey=\"{(key.OtherColumns.Select(c => c.MemberName)).Join(", ")}\"") + .Append($"ThisKey={CSharpTools.ToStringLiteral((key.ThisColumns.Select(c => c.MemberName)).Join(", "))}") + .Append($", OtherKey={CSharpTools.ToStringLiteral((key.OtherColumns.Select(c => c.MemberName)).Join(", "))}") .Append($", CanBeNull={(key.CanBeNull ? "true" : "false")}") ; if (key.BackReference != null) { if (key.KeyName.NotNullNorEmpty()) - classCode.Append($", KeyName=\"{key.KeyName}\""); + classCode.Append($", KeyName={CSharpTools.ToStringLiteral(key.KeyName)}"); if (key.BackReference.KeyName.NotNullNorEmpty()) - classCode.Append($", BackReferenceName=\"{key.BackReference.MemberName}\""); + classCode.Append($", BackReferenceName={CSharpTools.ToStringLiteral(key.BackReference.MemberName)}"); } else { @@ -551,7 +550,7 @@ void CodeTable(StringBuilder classCode, TableSchema table, bool addTableAttribut ? $"List<{key.OtherTable.TypeName}>" : key.OtherTable.TypeName; - classCode.AppendLine($" public {typeName} @{key.MemberName} {{ get; set; }}"); + classCode.AppendLine($" public {typeName} {key.MemberName} {{ get; set; }}"); } classCode.AppendLine(" }"); @@ -569,7 +568,7 @@ ExplorerItem GetTables(string header, ExplorerIcon icon, IEnumerable @{memberName} {{ get {{ return this.GetTable<@{t.TypeName}>(); }} }}"); + Code.AppendLine($" public ITable<{t.TypeName}> {memberName} {{ get {{ return this.GetTable<{t.TypeName}>(); }} }}"); CodeTable(_classCode, t, true); @@ -719,52 +718,24 @@ void ConvertSchema(string typeName) } } - static string ToCodeString(string text) - { - return "\"" + text.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""; - } - static string ConvertToCompilable(string name, bool capitalize) { - var query = - from c in name.TrimStart('@') - select c.IsLetterOrDigit() ? c : '_'; - - var sb = new StringBuilder(); - sb.Append(query.ToArray()); - - if (sb.Length == 0) - { - sb.Append('_'); - } - else + if (capitalize) { - if (sb[0].IsDigit()) - { - sb.Insert(0, "_"); - } - - if (capitalize) + var sb = new StringBuilder(name); + for (int i = 0; i < sb.Length; i++) { - for (int i = 0; i < sb.Length; i++) + if (char.IsLetter(sb[i])) { - if (Char.IsLetter(sb[i])) - { - sb[i] = Char.ToUpper(sb[i]); - break; - } + sb[i] = sb[i].ToUpper(); + break; } } - } - - name = sb.ToString(); - if (_keyWords.Contains(name) || name.StartsWith("__")) - { - name = '@' + name; + name = sb.ToString(); } - return name; + return CSharpTools.ToValidIdentifier(name); } } } diff --git a/Source/linq2db.LINQPad.csproj b/Source/linq2db.LINQPad.csproj index 96d6f75..3fd6214 100644 --- a/Source/linq2db.LINQPad.csproj +++ b/Source/linq2db.LINQPad.csproj @@ -185,6 +185,7 @@ True ConnectionViewModel.tt + @@ -200,36 +201,11 @@ - + + Designer + - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/appveyor.yml b/appveyor.yml index 1f47091..518fb7c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,12 +1,12 @@ -version: 2.5.1.{build} +version: 2.5.2.{build} os: Visual Studio 2017 configuration: Release assembly_info: patch: true file: '**\AssemblyInfo.*' - assembly_version: '2.5.1' - assembly_file_version: '2.5.1' - assembly_informational_version: '2.5.1' + assembly_version: '2.5.2' + assembly_file_version: '2.5.2' + assembly_informational_version: '2.5.2' before_build: - cmd: nuget restore build: