diff --git a/.gitignore b/.gitignore index a7dad64..ff295fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - #ignore thumbnails created by windows Thumbs.db #Ignore files build by Visual Studio @@ -29,3 +28,4 @@ _ReSharper*/ packages/*/ Packages/*/ .vs/** +*.lpx diff --git a/.tools/linq2db.t4models/Init.ps1 b/.tools/linq2db.t4models/Init.ps1 deleted file mode 100644 index f847998..0000000 --- a/.tools/linq2db.t4models/Init.ps1 +++ /dev/null @@ -1,14 +0,0 @@ -param($installPath, $toolsPath, $package) - -# get the active solution -$solution = Get-Interface $dte.Solution ([EnvDTE80.Solution2]) -$solutionPath = [System.IO.Path]::GetDirectoryName($solution.FullName) -$linq2dbToolsPath = [System.IO.Path]::Combine($solutionPath, ".tools", "linq2db.t4models") -$linq2dbContentPath = [System.IO.Path]::Combine($installPath, "content") - -# tools copy -xcopy $("$toolsPath\*.*") $("$linq2dbToolsPath\") /y /e - -# content copy for .Net Core & similar projects -xcopy $("$linq2dbContentPath\*.*") $("$linq2dbToolsPath\") /y /e - diff --git a/.tools/linq2db.t4models/LinqToDB.Templates/DataAnnotations.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/DataAnnotations.ttinclude deleted file mode 100644 index 70f22af..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/DataModel.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/DataModel.ttinclude deleted file mode 100644 index 95e6f52..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/EditableObject.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/EditableObject.ttinclude deleted file mode 100644 index dd4e4f2..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/Humanizer.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/Humanizer.ttinclude deleted file mode 100644 index 88f657b..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Access.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Access.ttinclude deleted file mode 100644 index 4d36a2c..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.DB2.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.DB2.ttinclude deleted file mode 100644 index 466ca8f..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Firebird.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Firebird.ttinclude deleted file mode 100644 index 156a47f..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Informix.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Informix.ttinclude deleted file mode 100644 index 0e6cc90..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.MySql.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.MySql.ttinclude deleted file mode 100644 index 3d96937..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Oracle.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Oracle.ttinclude deleted file mode 100644 index dabdefa..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.PostgreSQL.ttinclude deleted file mode 100644 index 2ac6c38..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SQLite.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SQLite.ttinclude deleted file mode 100644 index 6b04b24..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SapHana.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SapHana.ttinclude deleted file mode 100644 index 0cbb3e8..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SqlCe.ttinclude deleted file mode 100644 index 4160979..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SqlServer.SqlTypes.ttinclude deleted file mode 100644 index aded8bd..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.SqlServer.ttinclude deleted file mode 100644 index 74791db..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Sybase.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Sybase.ttinclude deleted file mode 100644 index 154c181..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Tools.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Tools.ttinclude deleted file mode 100644 index 44d4529..0000000 --- a/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.Tools.ttinclude +++ /dev/null @@ -1 +0,0 @@ -<#@ assembly name="$(SolutionDir).tools\linq2db.t4models\linq2db.dll" #> diff --git a/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/LinqToDB.ttinclude deleted file mode 100644 index efa6700..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/MultipleFiles.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/MultipleFiles.ttinclude deleted file mode 100644 index 4b43ba0..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/NotifyDataErrorInfo.ttinclude deleted file mode 100644 index 4663038..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/ObsoleteAttributes.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/ObsoleteAttributes.ttinclude deleted file mode 100644 index 94f1b05..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/PluralizationService.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/PluralizationService.ttinclude deleted file mode 100644 index 352edfb..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/README.md b/.tools/linq2db.t4models/LinqToDB.Templates/README.md deleted file mode 100644 index ae9d457..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/LinqToDB.Templates/Validation.ttinclude b/.tools/linq2db.t4models/LinqToDB.Templates/Validation.ttinclude deleted file mode 100644 index a31a6c8..0000000 --- a/.tools/linq2db.t4models/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/.tools/linq2db.t4models/linq2db.dll b/.tools/linq2db.t4models/linq2db.dll deleted file mode 100644 index b26b9b9..0000000 Binary files a/.tools/linq2db.t4models/linq2db.dll and /dev/null differ diff --git a/.tools/linq2db.t4models/LinqToDB.Templates/NotifyPropertyChanged.ttinclude b/LinqToDB.Templates/NotifyPropertyChanged.ttinclude similarity index 70% rename from .tools/linq2db.t4models/LinqToDB.Templates/NotifyPropertyChanged.ttinclude rename to LinqToDB.Templates/NotifyPropertyChanged.ttinclude index eda008e..b989fb7 100644 --- a/.tools/linq2db.t4models/LinqToDB.Templates/NotifyPropertyChanged.ttinclude +++ b/LinqToDB.Templates/NotifyPropertyChanged.ttinclude @@ -1,380 +1,382 @@ -<# - { - 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); - } -} -#> +<# + { + 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.BuildType().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.TypeBuilder = () => " " + type; + prop.IsAuto = false; + + if (prop.HasGetter) prop.GetBodyBuilders.Add(() => new [] { "return " + field.Name + ";" }); + if (prop.HasSetter) prop.SetBodyBuilders.Add(() => new [] { 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) + { + var setBody = prop.BuildSetBody().Select(s => "\t" + s).ToArray(); + prop.SetBodyBuilders.Clear(); + prop.SetBodyBuilders.Add(() => setBody); + + string getValue; + + var getBody = prop.BuildGetBody().ToArray(); + if (getBody.Length == 1 && getBody[0].StartsWith("return")) + { + getValue = getBody[0].Substring("return".Length).Trim(' ', '\t', ';'); + } + else + { + getValue = name; + } + + var insSpaces = setBody.Length > 1; + var n = 0; + + prop.SetBodyBuilders.Insert(n++, () => new [] {"if (" + getValue + " != value)", "{" }); + + if (ImplementNotifyPropertyChanging) + { + foreach (var dp in prop.Dependents) + prop.SetBodyBuilders.Insert(n++, () => new [] { "\tOn" + dp + "Changing();" }); + prop.SetBodyBuilders.Insert(n++, () => new [] { "" }); + } + + prop.SetBodyBuilders.Insert(n++, () => new [] { "\tBefore" + name + "Changed(value);" }); + + if (insSpaces) + { + prop.SetBodyBuilders.Insert(3, () => new [] { "" }); + prop.SetBodyBuilders.Add(() => new [] { "" }); + } + + prop.SetBodyBuilders.Add(() => new [] { "\tAfter" + name + "Changed();" }); + prop.SetBodyBuilders.Add(() => new [] { "" }); + + foreach (var dp in prop.Dependents) + prop.SetBodyBuilders.Add(() => new [] { "\tOn" + dp + "Changed();" }); + + prop.SetBodyBuilders.Add(() => new [] { "}" }); + + methods.Members.Insert(0, new MemberGroup + { + IsCompact = true, + Members = + { + new Method(() => "void", "Before" + name + "Changed", new Func[] { () => 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 Func[] { () => "string propertyName" }, () => OnPropertyChangedBody) + { + AccessModifier = AccessModifier.Protected + }, + new Method(() => "void", "OnPropertyChanged", new Func[] { () => "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 Func[] { () => "string propertyName" }, () => OnPropertyChangingBody) + { + AccessModifier = AccessModifier.Protected + }, + new Method(() => "void", "OnPropertyChanging", new Func[] { () => "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/.tools/linq2db.t4models/LinqToDB.Templates/T4Model.ttinclude b/LinqToDB.Templates/T4Model.ttinclude similarity index 85% rename from .tools/linq2db.t4models/LinqToDB.Templates/T4Model.ttinclude rename to LinqToDB.Templates/T4Model.ttinclude index 50ce91a..0d0ff67 100644 --- a/.tools/linq2db.t4models/LinqToDB.Templates/T4Model.ttinclude +++ b/LinqToDB.Templates/T4Model.ttinclude @@ -1,1482 +1,1509 @@ -<#@ 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); -} -#> +<#@ 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/linq2db)."); + 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}{1}", cl.Name, cl.GenericArguments.Count > 0 ? $"<{string.Join(", ", cl.GenericArguments)}>" : string.Empty); + + 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 List GenericArguments = new List(); + 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 Func TypeBuilder; + 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 string BuildType() { return TypeBuilder?.Invoke(); } + + 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.BuildType() ?? "").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.BuildType(), LenDiff(f.TypeLen, f.BuildType()), + 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(Func typeBuilder, string name) + { + TypeBuilder = typeBuilder; + 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.BuildType(), LenDiff(m.TypeLen, m.BuildType()), + 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(Func typeBuilder, string name) + { + TypeBuilder = typeBuilder; + 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.BuildType(), LenDiff(p.TypeLen, p.BuildType()), + 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.BuildGetBody()) + tt.Write("{0} ", t); + tt.Write("} "); + } + + if (p.HasSetter) + { + tt.Write("set { "); + foreach (var t in p.BuildSetBody()) + 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) + { + var getBody = p.BuildGetBody().ToArray(); + if (getBody.Length == 1) + { + tt.WriteLine("get {{ {0} }}", getBody[0]); + } + else + { + tt.WriteLine("get"); + tt.WriteLine("{"); + tt.PushIndent("\t"); + + foreach (var t in getBody) + tt.WriteLine(t); + + tt.PopIndent(); + tt.WriteLine("}"); + } + } + + if (p.HasSetter) + { + var setBody = p.BuildSetBody().ToArray(); + if (setBody.Length == 1) + { + tt.WriteLine("set {{ {0} }}", setBody[0]); + } + else + { + tt.WriteLine("set"); + tt.WriteLine("{"); + tt.PushIndent("\t"); + + foreach (var t in 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>> GetBodyBuilders = new List>>(); + public List>> SetBodyBuilders = new List>>(); + + public int GetterLen = 5; + public int SetterLen = 5; + + public Property() + { + } + + public Property(Func typeBuilder, string name, Func> getBodyBuilder = null, Func> setBodyBuilder = null) + { + TypeBuilder = typeBuilder; + Name = name; + + InitBody(getBodyBuilder, setBodyBuilder); + } + + 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 BuildGetBody()) + len += 1 + t.Length; + len += " }".Length; + } + + if (HasSetter) + { + len += " set {".Length; + foreach (var t in BuildSetBody()) + len += 1 + t.Length; + len += " }".Length; + } + + len += " }".Length; + + return len; + } + + public override void Render(GeneratedTextTransformation tt, bool isCompact) + { + if (!IsAuto && HasGetter) + { + var getBody = BuildGetBody().ToArray(); + if (getBody.Length == 1) + { + var t = getBody[0]; + + if (!t.StartsWith("return")) + { + t = "return " + t; + + if (!t.EndsWith(";")) + t += ";"; + + GetBodyBuilders.Clear(); + GetBodyBuilders.Add(() => new [] { t }); + } + } + } + + WriteProperty(tt, this, isCompact); + } + + public Property InitBody(Func> getBodyBuilder = null, Func> setBodyBuilder = null) + { + IsAuto = getBodyBuilder == null && setBodyBuilder == null; + + if (getBodyBuilder != null) GetBodyBuilders.Add(getBodyBuilder); + if (setBodyBuilder != null) SetBodyBuilders.Add(setBodyBuilder); + + if (!IsAuto) + { + HasGetter = getBodyBuilder != null; + HasSetter = setBodyBuilder != null; + } + + return this; + } + + public Property InitGetter(Func> getBodyBuilder) + { + return InitBody(getBodyBuilder, null); + } + + public IEnumerable BuildGetBody() + { + return GetBodyBuilders.SelectMany(builder => builder?.Invoke() ?? Array.Empty()); + } + + public IEnumerable BuildSetBody() + { + return SetBodyBuilders.SelectMany(builder => builder?.Invoke() ?? Array.Empty()); + } +} + +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}{10}", + am1, LenDiff(len1, am1), + mdf, LenDiff(mlen, mdf), + am2, LenDiff(len2, am2), + m.BuildType() == null ? "" : " ", + m.BuildType(), LenDiff(m.TypeLen, m.BuildType() ?? ""), + m.Name, + m.GenericArguments.Count > 0 ? $"<{string.Join(", ", m.GenericArguments)}>" : string.Empty); + + 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.ParameterBuilders.Count; i++) + { + if (i > 0) + tt.Write(", "); + tt.Write(m.ParameterBuilders[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.BuildBody()) + 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.BuildBody()) + { + 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 GenericArguments = new List(); + public List AfterSignature = new List(); + public List> ParameterBuilders = new List>(); + public List>> BodyBuilders = new List>>(); + + public Method() + { + } + + public Method(Func typeBuilder, string name, IEnumerable> parameterBuilders = null, params Func>[] bodyBuilders) + { + TypeBuilder = typeBuilder; + Name = name; + + if (parameterBuilders != null) ParameterBuilders.AddRange(parameterBuilders); + if (bodyBuilders != null) BodyBuilders.AddRange(bodyBuilders); + } + + public IEnumerable BuildBody() + { + return BodyBuilders.SelectMany(builder => builder?.Invoke() ?? Array.Empty()); + } + + 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 BuildBody()) + len += 1 + t.Length; + + len += " }".Length; + + return len; + } + + public override int CalcParamLen() + { + return ParameterBuilders.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/README.md b/README.md index de361bd..fdd9a1b 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ linq2db.LINQPad is a driver for [LINQPad](http://www.linqpad.net) that supports the following databases: - **DB2** (LUW, z/OS) *(client software must be installed)* +- **DB2 iSeries** (using [3rd-party provider](https://github.com/LinqToDB4iSeries/Linq2DB4iSeries)) *(iAccess 7.1+ software must be installed)* - **Firebird** - **Informix** *(client software must be installed)* - **Microsoft Access** @@ -14,7 +15,7 @@ linq2db.LINQPad is a driver for [LINQPad](http://www.linqpad.net) that supports - **PostgreSQL** - **SQLite** - **SAP HANA** *(client software must be installed)* -- **Sybase ASE** +- **SAP/Sybase ASE** *(client software must be installed)* ## Download diff --git a/Redist/IBM/IBM.Data.DB2.dll b/Redist/IBM/IBM.Data.DB2.dll deleted file mode 100644 index 09657a4..0000000 Binary files a/Redist/IBM/IBM.Data.DB2.dll and /dev/null differ diff --git a/Redist/IBM/IBM.Data.Informix.dll b/Redist/IBM/IBM.Data.Informix.dll deleted file mode 100644 index 5ed7ae3..0000000 Binary files a/Redist/IBM/IBM.Data.Informix.dll and /dev/null differ diff --git a/Redist/LINQPad.exe b/Redist/LINQPad.exe index 45c9b35..638c0da 100644 Binary files a/Redist/LINQPad.exe and b/Redist/LINQPad.exe differ diff --git a/Redist/Sybase/Sybase.AdoNet45.AseClient.dll b/Redist/Sybase/Sybase.AdoNet45.AseClient.dll deleted file mode 100644 index 390285f..0000000 Binary files a/Redist/Sybase/Sybase.AdoNet45.AseClient.dll and /dev/null differ diff --git a/Source/ConnectionViewModel.generated.cs b/Source/ConnectionViewModel.generated.cs index 8d1fdab..8563052 100644 --- a/Source/ConnectionViewModel.generated.cs +++ b/Source/ConnectionViewModel.generated.cs @@ -1,6 +1,6 @@ //--------------------------------------------------------------------------------------------------- // -// This code was generated by T4Model template for T4 (https://github.com/linq2db/t4models). +// This code was generated by T4Model template for T4 (https://github.com/linq2db/linq2db). // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //--------------------------------------------------------------------------------------------------- diff --git a/Source/ConnectionViewModel.tt b/Source/ConnectionViewModel.tt index 0719bd7..0d95e66 100644 --- a/Source/ConnectionViewModel.tt +++ b/Source/ConnectionViewModel.tt @@ -1,7 +1,7 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> + <#@ template debug="false" hostspecific="false" language="C#" #> <#@ output extension=".generated.cs" #> -<#@ include file="$(ProjectDir)LinqToDB.Templates\T4Model.ttinclude" #> -<#@ include file="$(ProjectDir)LinqToDB.Templates\NotifyPropertyChanged.ttinclude" #> +<#@ include file="$(ProjectDir)..\LinqToDB.Templates\T4Model.ttinclude" #> +<#@ include file="$(ProjectDir)..\LinqToDB.Templates\NotifyPropertyChanged.ttinclude" #> <# Model.Usings.Add("System.Collections.ObjectModel"); Model.Usings.Add("System.Windows"); @@ -34,10 +34,10 @@ new NotifyingProperty("string", "AppConfigPath"), new NotifyingProperty("string", "CustomConfiguration"), new NotifyingProperty("bool", "IsDynamic", "IsDynamic", "DynamicVisibility", "StaticVisibility"), - new NotifyingProperty("Visibility", "DynamicVisibility").InitGetter("IsDynamic ? Visibility.Visible : Visibility.Collapsed"), - new NotifyingProperty("Visibility", "StaticVisibility").InitGetter("!IsDynamic ? Visibility.Visible : Visibility.Collapsed"), + new NotifyingProperty("Visibility", "DynamicVisibility").InitGetter(() => new [] { "IsDynamic ? Visibility.Visible : Visibility.Collapsed" }), + new NotifyingProperty("Visibility", "StaticVisibility").InitGetter(() => new [] { "!IsDynamic ? Visibility.Visible : Visibility.Collapsed" }), new NotifyingProperty("ObservableCollection", "Providers")) ); GenerateModel(); -#> \ No newline at end of file +#> diff --git a/Source/DevDeploy.bat b/Source/DevDeploy.bat index 75211aa..661126d 100644 --- a/Source/DevDeploy.bat +++ b/Source/DevDeploy.bat @@ -1,8 +1,5 @@ -del linq2db.LINQPad.lpx -"C:\Program Files\7-Zip\7z.exe" -r a linq2db.LINQPad.zip %1\*.* -"C:\Program Files\7-Zip\7z.exe" -r d linq2db.LINQPad.zip %1\*.exe +call Pack.bat -ren linq2db.LINQPad.zip linq2db.LINQPad.lpx xcopy /i/y/s %1*.dll "%programdata%\LINQPad\Drivers\DataContext\4.0\linq2db.LINQPad (f19f8aed7feff67e)\*.*" xcopy /i/y/s %1*.pdb "%programdata%\LINQPad\Drivers\DataContext\4.0\linq2db.LINQPad (f19f8aed7feff67e)\*.*" xcopy /i/y/s %1*.xml "%programdata%\LINQPad\Drivers\DataContext\4.0\linq2db.LINQPad (f19f8aed7feff67e)\*.*" diff --git a/Source/Pack.bat b/Source/Pack.bat new file mode 100644 index 0000000..fb2959a --- /dev/null +++ b/Source/Pack.bat @@ -0,0 +1,6 @@ +del linq2db.LINQPad.lpx +del %1\LINQPad.exe +"C:\Program Files\7-Zip\7z.exe" -r a linq2db.LINQPad.zip %1\*.* + +ren linq2db.LINQPad.zip linq2db.LINQPad.lpx + diff --git a/Source/Properties/AssemblyInfo.cs b/Source/Properties/AssemblyInfo.cs index 1917327..f1dd17b 100644 --- a/Source/Properties/AssemblyInfo.cs +++ b/Source/Properties/AssemblyInfo.cs @@ -1,35 +1,4 @@ -using System.Reflection; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("linq2db.LINQPad")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("linq2db.LINQPad")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. [assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("78e25bf7-3de2-466a-a334-b080f2d4c3f0")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.5.1.0")] -[assembly: AssemblyFileVersion("2.5.1.0")] diff --git a/Source/SqlServerTypes/Loader.cs b/Source/SqlServerTypes/Loader.cs deleted file mode 100644 index 92f9384..0000000 --- a/Source/SqlServerTypes/Loader.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace SqlServerTypes -{ - /// - /// Utility methods related to CLR Types for SQL Server - /// - public class Utilities - { - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] - private static extern IntPtr LoadLibrary(string libname); - - /// - /// Loads the required native assemblies for the current architecture (x86 or x64) - /// - /// - /// Root path of the current application. Use Server.MapPath(".") for ASP.NET applications - /// and AppDomain.CurrentDomain.BaseDirectory for desktop applications. - /// - public static void LoadNativeAssemblies(string rootApplicationPath) - { - var nativeBinaryPath = IntPtr.Size > 4 - ? Path.Combine(rootApplicationPath, @"SqlServerTypes\x64\") - : Path.Combine(rootApplicationPath, @"SqlServerTypes\x86\"); - - LoadNativeAssembly(nativeBinaryPath, "msvcr120.dll"); - LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial140.dll"); - } - - private static void LoadNativeAssembly(string nativeBinaryPath, string assemblyName) - { - var path = Path.Combine(nativeBinaryPath, assemblyName); - var ptr = LoadLibrary(path); - if (ptr == IntPtr.Zero) - { - throw new Exception(string.Format( - "Error loading {0} (ErrorCode: {1})", - assemblyName, - Marshal.GetLastWin32Error())); - } - } - } -} \ No newline at end of file diff --git a/Source/SqlServerTypes/readme.htm b/Source/SqlServerTypes/readme.htm deleted file mode 100644 index f76d0bf..0000000 --- a/Source/SqlServerTypes/readme.htm +++ /dev/null @@ -1,61 +0,0 @@ - - - - Microsoft.SqlServer.Types - - - -
-

Action required to load native assemblies

-

- To deploy an application that uses spatial data types to a machine that does not have 'System CLR Types for SQL Server' installed you also need to deploy the native assembly SqlServerSpatial140.dll. Both x86 (32 bit) and x64 (64 bit) versions of this assembly have been added to your project under the SqlServerTypes\x86 and SqlServerTypes\x64 subdirectories. The native assembly msvcr120.dll is also included in case the C++ runtime is not installed. -

-

- You need to add code to load the correct one of these assemblies at runtime (depending on the current architecture). -

-

ASP.NET Web Sites

-

- For ASP.NET Web Sites, add the following block of code to the code behind file of the Web Form where you have added Report Viewer Control: -

-    Default.aspx.cs:
-        
-    public partial class _Default : System.Web.UI.Page
-    {
-        static bool _isSqlTypesLoaded = false;
-
-        public _Default()
-        {
-            if (!_isSqlTypesLoaded)
-            {
-                SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~"));
-                _isSqlTypesLoaded = true;
-            }
-            
-        }
-    }
-
-

-

ASP.NET Web Applications

-

- For ASP.NET Web Applications, add the following line of code to the Application_Start method in Global.asax.cs: -

    SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~/bin"));
-

-

Desktop Applications

-

- For desktop applications, add the following line of code to run before any spatial operations are performed: -

    SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);
-

-
- - \ No newline at end of file diff --git a/Source/SqlServerTypes/x64/SqlServerSpatial140.dll b/Source/SqlServerTypes/x64/SqlServerSpatial140.dll deleted file mode 100644 index 6e443bf..0000000 Binary files a/Source/SqlServerTypes/x64/SqlServerSpatial140.dll and /dev/null differ diff --git a/Source/SqlServerTypes/x64/msvcr120.dll b/Source/SqlServerTypes/x64/msvcr120.dll deleted file mode 100644 index 67937ce..0000000 Binary files a/Source/SqlServerTypes/x64/msvcr120.dll and /dev/null differ diff --git a/Source/SqlServerTypes/x86/SqlServerSpatial140.dll b/Source/SqlServerTypes/x86/SqlServerSpatial140.dll deleted file mode 100644 index 590a22a..0000000 Binary files a/Source/SqlServerTypes/x86/SqlServerSpatial140.dll and /dev/null differ diff --git a/Source/SqlServerTypes/x86/msvcr120.dll b/Source/SqlServerTypes/x86/msvcr120.dll deleted file mode 100644 index 23447f5..0000000 Binary files a/Source/SqlServerTypes/x86/msvcr120.dll and /dev/null differ diff --git a/Source/XmlFormatter.cs b/Source/XmlFormatter.cs index 25edeee..44597c4 100644 --- a/Source/XmlFormatter.cs +++ b/Source/XmlFormatter.cs @@ -622,8 +622,11 @@ abstract class ValueFormatter { public abstract Type Type { get; } +// Warning CS0649 Field 'XmlFormatter.ValueFormatter.Font' is never assigned to, and will always have its default value null +#pragma warning disable 649 public string Font; public string Size; +#pragma warning restore 649 public bool NoWrap; public abstract string FormatValue(object value); diff --git a/Source/app.config b/Source/app.config deleted file mode 100644 index 82d8316..0000000 --- a/Source/app.config +++ /dev/null @@ -1,49 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/header.xml b/Source/header.xml index 918caa3..8778755 100644 --- a/Source/header.xml +++ b/Source/header.xml @@ -1,5 +1,5 @@  linq2db.LINQPad.dll - http://linq2db.LINQPad + https://github.com/linq2db/linq2db.LINQPad diff --git a/Source/linq2db.LINQPad.csproj b/Source/linq2db.LINQPad.csproj index 3fd6214..cfb070d 100644 --- a/Source/linq2db.LINQPad.csproj +++ b/Source/linq2db.LINQPad.csproj @@ -1,281 +1,109 @@ - - - - - Debug - AnyCPU - {78E25BF7-3DE2-466A-A334-B080F2D4C3F0} - Library - Properties - LinqToDB.LINQPad - linq2db.LINQPad - v4.5.2 - 512 - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - AnyCPU - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AnyCPU - - - true - - - linq2db.snk - - - - ..\packages\CodeJam.2.1.1\lib\net45\CodeJam.dll - - - ..\packages\FirebirdSql.Data.FirebirdClient.6.1.0\lib\net452\FirebirdSql.Data.FirebirdClient.dll - - - ..\packages\Google.Protobuf.3.6.0\lib\net45\Google.Protobuf.dll - - - ..\packages\JetBrains.Annotations.2018.2.1\lib\net20\JetBrains.Annotations.dll - - - ..\packages\linq2db.2.5.1\lib\net45\linq2db.dll - - - False - ..\Redist\LINQPad.exe - - - ..\packages\linq2db4iSeries.2.5.0\lib\net45\LinqToDB.DataProvider.DB2iSeries.dll - - - ..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - - ..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - - - ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.1\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll - - - ..\packages\Microsoft.Extensions.Logging.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.dll - - - ..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll - - - ..\packages\Microsoft.SqlServer.Types.14.0.314.76\lib\net40\Microsoft.SqlServer.Types.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - - - ..\packages\MySql.Data.8.0.12\lib\net452\MySql.Data.dll - - - ..\packages\Npgsql.4.0.2\lib\net451\Npgsql.dll - - - ..\packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll - True - - - - - - ..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll - - - - - - - - - True - - - - - ..\packages\System.Data.SQLite.Core.1.0.108.0\lib\net451\System.Data.SQLite.dll - - - ..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll - True - - - - - - - - - ..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll - - - ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll - True - - - ..\packages\System.Threading.Tasks.Extensions.4.5.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - - - - ..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll - - - - - - - - - - - ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.dll - - - ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll - - - ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll - - - ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll - - - ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.DataGrid.dll - - - ..\packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.Toolkit.dll - - - - - ConnectionDialog.xaml - - - - True - True - ConnectionViewModel.tt - - - - - - - - - - - - - - - - - - - Designer - - - - - - - - PreserveNewest - - - TextTemplatingFileGenerator - ConnectionViewModel.generated.cs - - - PreserveNewest - - - PreserveNewest - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - - MSBuild:Compile - Designer - - - - - - - - - - - - - if not exist "$(TargetDir)x86" md "$(TargetDir)x86" - xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86" - if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64" - xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64" + - xcopy /s /y "$(SolutionDir)Redist\IBM\*.dll" "$(TargetDir)" - xcopy /s /y "$(SolutionDir)Redist\Sybase\*.dll" "$(TargetDir)" - $(ProjectDir)DevDeploy.bat $(TargetDir) - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file + + net452 + LinqToDB.LINQPad + linq2db + linq2db.LINQPad + $(Product) + 2.6.0 + $(Version) + $(Version) + Copyright © 2018 Igor Tkachev, Ilya Chudin, Svyatoslav Danyliv, Dmitry Lukashenko + true + linq2db.snk + false + + + + + + + + + + + + + + + + + + + + ..\Redist\LINQPad.exe + + + + + + + + + + + + + PreserveNewest + + + MSBuild:Compile + + + MSBuild:Compile + + + TextTemplatingFileGenerator + ConnectionViewModel.generated.cs + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + True + True + ConnectionViewModel.tt + + + Code + + + + + + + + + + + $(MSBuildToolsPath)\Microsoft.CSharp.targets + latest + + + true + + AnyCPU + + + + + + + + + false + + + + diff --git a/Source/linq2db.LINQPad.lpx b/Source/linq2db.LINQPad.lpx deleted file mode 100644 index c1c7c68..0000000 Binary files a/Source/linq2db.LINQPad.lpx and /dev/null differ diff --git a/Source/packages.config b/Source/packages.config deleted file mode 100644 index fbbe20d..0000000 --- a/Source/packages.config +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 518fb7c..1b7e16f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,19 +1,19 @@ -version: 2.5.2.{build} +version: 2.6.0.{build} os: Visual Studio 2017 configuration: Release assembly_info: patch: true file: '**\AssemblyInfo.*' - assembly_version: '2.5.2' - assembly_file_version: '2.5.2' - assembly_informational_version: '2.5.2' + assembly_version: '2.6.0' + assembly_file_version: '2.6.0' + assembly_informational_version: '2.6.0' before_build: - cmd: nuget restore build: project: linq2db.LINQPad.sln verbosity: minimal after_build: -- cmd: xcopy Source\bin\Release\linq2db.LINQPad.lpx .\ /y +- cmd: xcopy Source\linq2db.LINQPad.lpx .\ /y artifacts: - path: linq2db.LINQPad.lpx diff --git a/linq2db.LINQPad.lpx b/linq2db.LINQPad.lpx deleted file mode 100644 index 7fa2ac7..0000000 Binary files a/linq2db.LINQPad.lpx and /dev/null differ diff --git a/linq2db.LINQPad.sln b/linq2db.LINQPad.sln index ddeb0fd..2071f7b 100644 --- a/linq2db.LINQPad.sln +++ b/linq2db.LINQPad.sln @@ -3,28 +3,31 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27428.2043 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linq2db.LINQPad", "Source\linq2db.LINQPad.csproj", "{78E25BF7-3DE2-466A-A334-B080F2D4C3F0}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{48EE7991-A24D-4512-BB48-E947A57E02EA}" ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml README.md = README.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linq2db.LINQPad", "Source\linq2db.LINQPad.csproj", "{73352DC5-D33E-4BE6-A787-6F91107B3D7C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {78E25BF7-3DE2-466A-A334-B080F2D4C3F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78E25BF7-3DE2-466A-A334-B080F2D4C3F0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {78E25BF7-3DE2-466A-A334-B080F2D4C3F0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78E25BF7-3DE2-466A-A334-B080F2D4C3F0}.Release|Any CPU.Build.0 = Release|Any CPU + {73352DC5-D33E-4BE6-A787-6F91107B3D7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {73352DC5-D33E-4BE6-A787-6F91107B3D7C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {73352DC5-D33E-4BE6-A787-6F91107B3D7C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {73352DC5-D33E-4BE6-A787-6F91107B3D7C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {73352DC5-D33E-4BE6-A787-6F91107B3D7C} = {48EE7991-A24D-4512-BB48-E947A57E02EA} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {17946F59-D105-4BD7-8C31-5B14CB8A4FE2} EndGlobalSection