diff options
| author | Rob Mensching <rob@firegiant.com> | 2020-06-03 02:19:16 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2020-06-03 02:23:16 -0700 |
| commit | 9317f7c8ea709da55e4602eaaba06952bbf315b7 (patch) | |
| tree | 51e8348f891041dcc160a6b79e8965ca6a908b9d /src/WixToolset.Core | |
| parent | d529525a1e331f3ef9ec2707791c99bd78fdd82f (diff) | |
| download | wix-9317f7c8ea709da55e4602eaaba06952bbf315b7.tar.gz wix-9317f7c8ea709da55e4602eaaba06952bbf315b7.tar.bz2 wix-9317f7c8ea709da55e4602eaaba06952bbf315b7.zip | |
Redesign CustomTable tuples to support resolving binary columns
Diffstat (limited to 'src/WixToolset.Core')
| -rw-r--r-- | src/WixToolset.Core/Bind/ResolveFieldsCommand.cs | 57 | ||||
| -rw-r--r-- | src/WixToolset.Core/Compiler.cs | 275 |
2 files changed, 193 insertions, 139 deletions
diff --git a/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs b/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs index 3e680a98..af7e262a 100644 --- a/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs +++ b/src/WixToolset.Core/Bind/ResolveFieldsCommand.cs | |||
| @@ -4,7 +4,9 @@ namespace WixToolset.Core.Bind | |||
| 4 | { | 4 | { |
| 5 | using System; | 5 | using System; |
| 6 | using System.Collections.Generic; | 6 | using System.Collections.Generic; |
| 7 | using System.Linq; | ||
| 7 | using WixToolset.Data; | 8 | using WixToolset.Data; |
| 9 | using WixToolset.Data.Tuples; | ||
| 8 | using WixToolset.Extensibility; | 10 | using WixToolset.Extensibility; |
| 9 | using WixToolset.Extensibility.Data; | 11 | using WixToolset.Extensibility.Data; |
| 10 | using WixToolset.Extensibility.Services; | 12 | using WixToolset.Extensibility.Services; |
| @@ -42,6 +44,9 @@ namespace WixToolset.Core.Bind | |||
| 42 | 44 | ||
| 43 | var fileResolver = new FileResolver(this.BindPaths, this.Extensions); | 45 | var fileResolver = new FileResolver(this.BindPaths, this.Extensions); |
| 44 | 46 | ||
| 47 | // Build the column lookup only when needed. | ||
| 48 | Dictionary<string, WixCustomTableColumnTuple> customColumnsById = null; | ||
| 49 | |||
| 45 | foreach (var sections in this.Intermediate.Sections) | 50 | foreach (var sections in this.Intermediate.Sections) |
| 46 | { | 51 | { |
| 47 | foreach (var tuple in sections.Tuples) | 52 | foreach (var tuple in sections.Tuples) |
| @@ -53,13 +58,37 @@ namespace WixToolset.Core.Bind | |||
| 53 | continue; | 58 | continue; |
| 54 | } | 59 | } |
| 55 | 60 | ||
| 61 | var fieldType = field.Type; | ||
| 62 | |||
| 63 | // Custom table cells require an extra look up to the column definition as the | ||
| 64 | // cell's data type is always a string (because strings can store anything) but | ||
| 65 | // the column definition may be more specific. | ||
| 66 | if (tuple.Definition.Type == TupleDefinitionType.WixCustomTableCell) | ||
| 67 | { | ||
| 68 | // We only care about the Data in a CustomTable cell. | ||
| 69 | if (field.Name != nameof(WixCustomTableCellTupleFields.Data)) | ||
| 70 | { | ||
| 71 | continue; | ||
| 72 | } | ||
| 73 | |||
| 74 | if (customColumnsById == null) | ||
| 75 | { | ||
| 76 | customColumnsById = this.Intermediate.Sections.SelectMany(s => s.Tuples.OfType<WixCustomTableColumnTuple>()).ToDictionary(t => t.Id.Id); | ||
| 77 | } | ||
| 78 | |||
| 79 | if (customColumnsById.TryGetValue(tuple.Fields[(int)WixCustomTableCellTupleFields.TableRef].AsString() + "/" + tuple.Fields[(int)WixCustomTableCellTupleFields.ColumnRef].AsString(), out var customColumn)) | ||
| 80 | { | ||
| 81 | fieldType = customColumn.Type; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 56 | var isDefault = true; | 85 | var isDefault = true; |
| 57 | 86 | ||
| 58 | // Check to make sure we're in a scenario where we can handle variable resolution. | 87 | // Check to make sure we're in a scenario where we can handle variable resolution. |
| 59 | if (null != delayedFields) | 88 | if (null != delayedFields) |
| 60 | { | 89 | { |
| 61 | // resolve localization and wix variables | 90 | // resolve localization and wix variables |
| 62 | if (field.Type == IntermediateFieldType.String) | 91 | if (fieldType == IntermediateFieldType.String) |
| 63 | { | 92 | { |
| 64 | var original = field.AsString(); | 93 | var original = field.AsString(); |
| 65 | if (!String.IsNullOrEmpty(original)) | 94 | if (!String.IsNullOrEmpty(original)) |
| @@ -87,7 +116,7 @@ namespace WixToolset.Core.Bind | |||
| 87 | } | 116 | } |
| 88 | 117 | ||
| 89 | // Resolve file paths | 118 | // Resolve file paths |
| 90 | if (field.Type == IntermediateFieldType.Path) | 119 | if (fieldType == IntermediateFieldType.Path) |
| 91 | { | 120 | { |
| 92 | var objectField = field.AsPath(); | 121 | var objectField = field.AsPath(); |
| 93 | 122 | ||
| @@ -226,29 +255,5 @@ namespace WixToolset.Core.Bind | |||
| 226 | 255 | ||
| 227 | this.DelayedFields = delayedFields; | 256 | this.DelayedFields = delayedFields; |
| 228 | } | 257 | } |
| 229 | |||
| 230 | #if false | ||
| 231 | private string ResolveFile(string source, string type, SourceLineNumber sourceLineNumbers, BindStage bindStage = BindStage.Normal) | ||
| 232 | { | ||
| 233 | string path = null; | ||
| 234 | foreach (var extension in this.Extensions) | ||
| 235 | { | ||
| 236 | path = extension.ResolveFile(source, type, sourceLineNumbers, bindStage); | ||
| 237 | if (null != path) | ||
| 238 | { | ||
| 239 | break; | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | throw new NotImplementedException(); // need to do default binder stuff | ||
| 244 | |||
| 245 | //if (null == path) | ||
| 246 | //{ | ||
| 247 | // throw new WixFileNotFoundException(sourceLineNumbers, source, type); | ||
| 248 | //} | ||
| 249 | |||
| 250 | //return path; | ||
| 251 | } | ||
| 252 | #endif | ||
| 253 | } | 258 | } |
| 254 | } | 259 | } |
diff --git a/src/WixToolset.Core/Compiler.cs b/src/WixToolset.Core/Compiler.cs index 32e9b9d6..35a73e00 100644 --- a/src/WixToolset.Core/Compiler.cs +++ b/src/WixToolset.Core/Compiler.cs | |||
| @@ -8,6 +8,7 @@ namespace WixToolset.Core | |||
| 8 | using System.Diagnostics.CodeAnalysis; | 8 | using System.Diagnostics.CodeAnalysis; |
| 9 | using System.Globalization; | 9 | using System.Globalization; |
| 10 | using System.IO; | 10 | using System.IO; |
| 11 | using System.Linq; | ||
| 11 | using System.Text.RegularExpressions; | 12 | using System.Text.RegularExpressions; |
| 12 | using System.Xml.Linq; | 13 | using System.Xml.Linq; |
| 13 | using WixToolset.Data; | 14 | using WixToolset.Data; |
| @@ -3667,20 +3668,8 @@ namespace WixToolset.Core | |||
| 3667 | { | 3668 | { |
| 3668 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | 3669 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); |
| 3669 | string tableId = null; | 3670 | string tableId = null; |
| 3670 | 3671 | var unreal = false; | |
| 3671 | string categories = null; | 3672 | var columns = new List<WixCustomTableColumnTuple>(); |
| 3672 | var columnCount = 0; | ||
| 3673 | string columnNames = null; | ||
| 3674 | string columnTypes = null; | ||
| 3675 | string descriptions = null; | ||
| 3676 | string keyColumns = null; | ||
| 3677 | string keyTables = null; | ||
| 3678 | string maxValues = null; | ||
| 3679 | string minValues = null; | ||
| 3680 | string modularizations = null; | ||
| 3681 | string primaryKeys = null; | ||
| 3682 | string sets = null; | ||
| 3683 | var bootstrapperApplicationData = false; | ||
| 3684 | 3673 | ||
| 3685 | foreach (var attrib in node.Attributes()) | 3674 | foreach (var attrib in node.Attributes()) |
| 3686 | { | 3675 | { |
| @@ -3692,7 +3681,7 @@ namespace WixToolset.Core | |||
| 3692 | tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); | 3681 | tableId = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); |
| 3693 | break; | 3682 | break; |
| 3694 | case "Unreal": | 3683 | case "Unreal": |
| 3695 | bootstrapperApplicationData = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); | 3684 | unreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib); |
| 3696 | break; | 3685 | break; |
| 3697 | default: | 3686 | default: |
| 3698 | this.Core.UnexpectedAttribute(node, attrib); | 3687 | this.Core.UnexpectedAttribute(node, attrib); |
| @@ -3722,22 +3711,20 @@ namespace WixToolset.Core | |||
| 3722 | switch (child.Name.LocalName) | 3711 | switch (child.Name.LocalName) |
| 3723 | { | 3712 | { |
| 3724 | case "Column": | 3713 | case "Column": |
| 3725 | ++columnCount; | ||
| 3726 | |||
| 3727 | var category = String.Empty; | ||
| 3728 | string columnName = null; | 3714 | string columnName = null; |
| 3729 | string columnType = null; | 3715 | var category = String.Empty; |
| 3716 | IntermediateFieldType? columnType = null; | ||
| 3730 | var description = String.Empty; | 3717 | var description = String.Empty; |
| 3731 | var keyColumn = CompilerConstants.IntegerNotSet; | 3718 | int? keyColumn = null; |
| 3732 | var keyTable = String.Empty; | 3719 | var keyTable = String.Empty; |
| 3733 | var localizable = false; | 3720 | var localizable = false; |
| 3734 | var maxValue = CompilerConstants.LongNotSet; | 3721 | long? maxValue = null; |
| 3735 | var minValue = CompilerConstants.LongNotSet; | 3722 | long? minValue = null; |
| 3736 | var modularization = "None"; | 3723 | var modularization = WixCustomTableColumnModularizeType.None; |
| 3737 | var nullable = false; | 3724 | var nullable = false; |
| 3738 | var primaryKey = false; | 3725 | var primaryKey = false; |
| 3739 | var setValues = String.Empty; | 3726 | var setValues = String.Empty; |
| 3740 | string typeName = null; | 3727 | var columnUnreal = false; |
| 3741 | var width = 0; | 3728 | var width = 0; |
| 3742 | 3729 | ||
| 3743 | foreach (var childAttrib in child.Attributes()) | 3730 | foreach (var childAttrib in child.Attributes()) |
| @@ -3769,7 +3756,43 @@ namespace WixToolset.Core | |||
| 3769 | minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue); | 3756 | minValue = this.Core.GetAttributeLongValue(childSourceLineNumbers, childAttrib, Int32.MinValue + 1, Int32.MaxValue); |
| 3770 | break; | 3757 | break; |
| 3771 | case "Modularize": | 3758 | case "Modularize": |
| 3772 | modularization = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); | 3759 | var modularizeValue = this.Core.GetAttributeValue(childSourceLineNumbers, childAttrib); |
| 3760 | switch (modularizeValue) | ||
| 3761 | { | ||
| 3762 | case "column": | ||
| 3763 | modularization = WixCustomTableColumnModularizeType.Column; | ||
| 3764 | break; | ||
| 3765 | case "companionFile": | ||
| 3766 | modularization = WixCustomTableColumnModularizeType.CompanionFile; | ||
| 3767 | break; | ||
| 3768 | case "condition": | ||
| 3769 | modularization = WixCustomTableColumnModularizeType.Condition; | ||
| 3770 | break; | ||
| 3771 | case "controlEventArgument": | ||
| 3772 | modularization = WixCustomTableColumnModularizeType.ControlEventArgument; | ||
| 3773 | break; | ||
| 3774 | case "controlText": | ||
| 3775 | modularization = WixCustomTableColumnModularizeType.ControlText; | ||
| 3776 | break; | ||
| 3777 | case "icon": | ||
| 3778 | modularization = WixCustomTableColumnModularizeType.Icon; | ||
| 3779 | break; | ||
| 3780 | case "none": | ||
| 3781 | modularization = WixCustomTableColumnModularizeType.None; | ||
| 3782 | break; | ||
| 3783 | case "property": | ||
| 3784 | modularization = WixCustomTableColumnModularizeType.Property; | ||
| 3785 | break; | ||
| 3786 | case "semicolonDelimited": | ||
| 3787 | modularization = WixCustomTableColumnModularizeType.SemicolonDelimited; | ||
| 3788 | break; | ||
| 3789 | case "": | ||
| 3790 | break; | ||
| 3791 | default: | ||
| 3792 | this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Modularize", modularizeValue, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited")); | ||
| 3793 | columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below. | ||
| 3794 | break; | ||
| 3795 | } | ||
| 3773 | break; | 3796 | break; |
| 3774 | case "Nullable": | 3797 | case "Nullable": |
| 3775 | nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); | 3798 | nullable = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); |
| @@ -3785,24 +3808,28 @@ namespace WixToolset.Core | |||
| 3785 | switch (typeValue) | 3808 | switch (typeValue) |
| 3786 | { | 3809 | { |
| 3787 | case "binary": | 3810 | case "binary": |
| 3788 | typeName = "OBJECT"; | 3811 | columnType = IntermediateFieldType.Path; |
| 3789 | break; | 3812 | break; |
| 3790 | case "int": | 3813 | case "int": |
| 3791 | typeName = "SHORT"; | 3814 | columnType = IntermediateFieldType.Number; |
| 3792 | break; | 3815 | break; |
| 3793 | case "string": | 3816 | case "string": |
| 3794 | typeName = "CHAR"; | 3817 | columnType = IntermediateFieldType.String; |
| 3795 | break; | 3818 | break; |
| 3796 | case "": | 3819 | case "": |
| 3797 | break; | 3820 | break; |
| 3798 | default: | 3821 | default: |
| 3799 | this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string")); | 3822 | this.Core.Write(ErrorMessages.IllegalAttributeValue(childSourceLineNumbers, child.Name.LocalName, "Type", typeValue, "binary", "int", "string")); |
| 3823 | columnType = IntermediateFieldType.String; // set a value to prevent expected attribute error below. | ||
| 3800 | break; | 3824 | break; |
| 3801 | } | 3825 | } |
| 3802 | break; | 3826 | break; |
| 3803 | case "Width": | 3827 | case "Width": |
| 3804 | width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue); | 3828 | width = this.Core.GetAttributeIntegerValue(childSourceLineNumbers, childAttrib, 0, Int32.MaxValue); |
| 3805 | break; | 3829 | break; |
| 3830 | case "Unreal": | ||
| 3831 | columnUnreal = YesNoType.Yes == this.Core.GetAttributeYesNoValue(childSourceLineNumbers, childAttrib); | ||
| 3832 | break; | ||
| 3806 | default: | 3833 | default: |
| 3807 | this.Core.UnexpectedAttribute(child, childAttrib); | 3834 | this.Core.UnexpectedAttribute(child, childAttrib); |
| 3808 | break; | 3835 | break; |
| @@ -3814,100 +3841,59 @@ namespace WixToolset.Core | |||
| 3814 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id")); | 3841 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Id")); |
| 3815 | } | 3842 | } |
| 3816 | 3843 | ||
| 3817 | if (null == typeName) | 3844 | if (!columnType.HasValue) |
| 3818 | { | 3845 | { |
| 3819 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type")); | 3846 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Type")); |
| 3820 | } | 3847 | } |
| 3821 | else if ("SHORT" == typeName) | 3848 | else if (columnType == IntermediateFieldType.Number) |
| 3822 | { | 3849 | { |
| 3823 | if (2 != width && 4 != width) | 3850 | if (2 != width && 4 != width) |
| 3824 | { | 3851 | { |
| 3825 | this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width)); | 3852 | this.Core.Write(ErrorMessages.CustomTableIllegalColumnWidth(childSourceLineNumbers, child.Name.LocalName, "Width", width)); |
| 3826 | } | 3853 | } |
| 3827 | columnType = String.Concat(nullable ? "I" : "i", width); | ||
| 3828 | } | 3854 | } |
| 3829 | else if ("CHAR" == typeName) | 3855 | else if (columnType == IntermediateFieldType.Path) |
| 3830 | { | 3856 | { |
| 3831 | var typeChar = localizable ? "l" : "s"; | 3857 | if (String.IsNullOrEmpty(category)) |
| 3832 | columnType = String.Concat(nullable ? typeChar.ToUpper(CultureInfo.InvariantCulture) : typeChar.ToLower(CultureInfo.InvariantCulture), width); | ||
| 3833 | } | ||
| 3834 | else if ("OBJECT" == typeName) | ||
| 3835 | { | ||
| 3836 | if ("Binary" != category) | ||
| 3837 | { | 3858 | { |
| 3838 | this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers)); | 3859 | category = "Binary"; |
| 3839 | } | 3860 | } |
| 3840 | columnType = String.Concat(nullable ? "V" : "v", width); | 3861 | else if (category != "Binary") |
| 3841 | } | ||
| 3842 | |||
| 3843 | this.Core.ParseForExtensionElements(child); | ||
| 3844 | |||
| 3845 | columnNames = String.Concat(columnNames, null == columnNames ? String.Empty : "\t", columnName); | ||
| 3846 | columnTypes = String.Concat(columnTypes, null == columnTypes ? String.Empty : "\t", columnType); | ||
| 3847 | if (primaryKey) | ||
| 3848 | { | ||
| 3849 | primaryKeys = String.Concat(primaryKeys, null == primaryKeys ? String.Empty : "\t", columnName); | ||
| 3850 | } | ||
| 3851 | |||
| 3852 | minValues = String.Concat(minValues, null == minValues ? String.Empty : "\t", CompilerConstants.LongNotSet != minValue ? minValue.ToString(CultureInfo.InvariantCulture) : String.Empty); | ||
| 3853 | maxValues = String.Concat(maxValues, null == maxValues ? String.Empty : "\t", CompilerConstants.LongNotSet != maxValue ? maxValue.ToString(CultureInfo.InvariantCulture) : String.Empty); | ||
| 3854 | keyTables = String.Concat(keyTables, null == keyTables ? String.Empty : "\t", keyTable); | ||
| 3855 | keyColumns = String.Concat(keyColumns, null == keyColumns ? String.Empty : "\t", CompilerConstants.IntegerNotSet != keyColumn ? keyColumn.ToString(CultureInfo.InvariantCulture) : String.Empty); | ||
| 3856 | categories = String.Concat(categories, null == categories ? String.Empty : "\t", category); | ||
| 3857 | sets = String.Concat(sets, null == sets ? String.Empty : "\t", setValues); | ||
| 3858 | descriptions = String.Concat(descriptions, null == descriptions ? String.Empty : "\t", description); | ||
| 3859 | modularizations = String.Concat(modularizations, null == modularizations ? String.Empty : "\t", modularization); | ||
| 3860 | |||
| 3861 | break; | ||
| 3862 | case "Row": | ||
| 3863 | string dataValue = null; | ||
| 3864 | |||
| 3865 | foreach (var childAttrib in child.Attributes()) | ||
| 3866 | { | ||
| 3867 | this.Core.ParseExtensionAttribute(child, childAttrib); | ||
| 3868 | } | ||
| 3869 | |||
| 3870 | foreach (var data in child.Elements()) | ||
| 3871 | { | ||
| 3872 | var dataSourceLineNumbers = Preprocessor.GetSourceLineNumbers(data); | ||
| 3873 | switch (data.Name.LocalName) | ||
| 3874 | { | 3862 | { |
| 3875 | case "Data": | 3863 | this.Core.Write(ErrorMessages.ExpectedBinaryCategory(childSourceLineNumbers)); |
| 3876 | columnName = null; | ||
| 3877 | foreach (var dataAttrib in data.Attributes()) | ||
| 3878 | { | ||
| 3879 | switch (dataAttrib.Name.LocalName) | ||
| 3880 | { | ||
| 3881 | case "Column": | ||
| 3882 | columnName = this.Core.GetAttributeValue(dataSourceLineNumbers, dataAttrib); | ||
| 3883 | break; | ||
| 3884 | default: | ||
| 3885 | this.Core.UnexpectedAttribute(data, dataAttrib); | ||
| 3886 | break; | ||
| 3887 | } | ||
| 3888 | } | ||
| 3889 | |||
| 3890 | if (null == columnName) | ||
| 3891 | { | ||
| 3892 | this.Core.Write(ErrorMessages.ExpectedAttribute(dataSourceLineNumbers, data.Name.LocalName, "Column")); | ||
| 3893 | } | ||
| 3894 | |||
| 3895 | dataValue = String.Concat(dataValue, null == dataValue ? String.Empty : WixCustomRowTuple.FieldSeparator.ToString(), columnName, ":", Common.GetInnerText(data)); | ||
| 3896 | break; | ||
| 3897 | } | 3864 | } |
| 3898 | } | 3865 | } |
| 3899 | 3866 | ||
| 3900 | this.Core.CreateSimpleReference(sourceLineNumbers, TupleDefinitions.WixCustomTable, tableId); | 3867 | this.Core.ParseForExtensionElements(child); |
| 3901 | 3868 | ||
| 3902 | if (!this.Core.EncounteredError) | 3869 | if (!this.Core.EncounteredError) |
| 3903 | { | 3870 | { |
| 3904 | this.Core.AddTuple(new WixCustomRowTuple(childSourceLineNumbers) | 3871 | var attributes = primaryKey ? WixCustomTableColumnTupleAttributes.PrimaryKey : WixCustomTableColumnTupleAttributes.None; |
| 3872 | attributes |= localizable ? WixCustomTableColumnTupleAttributes.Localizable : WixCustomTableColumnTupleAttributes.None; | ||
| 3873 | attributes |= nullable ? WixCustomTableColumnTupleAttributes.Nullable : WixCustomTableColumnTupleAttributes.None; | ||
| 3874 | attributes |= columnUnreal ? WixCustomTableColumnTupleAttributes.Unreal : WixCustomTableColumnTupleAttributes.None; | ||
| 3875 | |||
| 3876 | columns.Add(new WixCustomTableColumnTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, columnName)) | ||
| 3905 | { | 3877 | { |
| 3906 | Table = tableId, | 3878 | TableRef = tableId, |
| 3907 | FieldData = dataValue, | 3879 | Name = columnName, |
| 3880 | Type = columnType.Value, | ||
| 3881 | Attributes = attributes, | ||
| 3882 | Width = width, | ||
| 3883 | Category = category, | ||
| 3884 | Description = description, | ||
| 3885 | KeyColumn = keyColumn, | ||
| 3886 | KeyTable = keyTable, | ||
| 3887 | MaxValue = maxValue, | ||
| 3888 | MinValue = minValue, | ||
| 3889 | Modularize = modularization, | ||
| 3890 | Set = setValues, | ||
| 3908 | }); | 3891 | }); |
| 3909 | } | 3892 | } |
| 3910 | break; | 3893 | break; |
| 3894 | case "Row": | ||
| 3895 | this.ParseRow(child, tableId); | ||
| 3896 | break; | ||
| 3911 | default: | 3897 | default: |
| 3912 | this.Core.UnexpectedElement(node, child); | 3898 | this.Core.UnexpectedElement(node, child); |
| 3913 | break; | 3899 | break; |
| @@ -3919,35 +3905,98 @@ namespace WixToolset.Core | |||
| 3919 | } | 3905 | } |
| 3920 | } | 3906 | } |
| 3921 | 3907 | ||
| 3922 | if (0 < columnCount) | 3908 | if (columns.Count > 0) |
| 3923 | { | 3909 | { |
| 3924 | if (null == primaryKeys || 0 == primaryKeys.Length) | 3910 | if (!columns.Where(c => c.PrimaryKey).Any()) |
| 3925 | { | 3911 | { |
| 3926 | this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers)); | 3912 | this.Core.Write(ErrorMessages.CustomTableMissingPrimaryKey(sourceLineNumbers)); |
| 3927 | } | 3913 | } |
| 3928 | 3914 | ||
| 3929 | if (!this.Core.EncounteredError) | 3915 | if (!this.Core.EncounteredError) |
| 3930 | { | 3916 | { |
| 3917 | var columnNames = String.Join(new string(WixCustomTableTuple.ColumnNamesSeparator, 1), columns.Select(c => c.Name)); | ||
| 3918 | |||
| 3931 | this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId)) | 3919 | this.Core.AddTuple(new WixCustomTableTuple(sourceLineNumbers, new Identifier(AccessModifier.Public, tableId)) |
| 3932 | { | 3920 | { |
| 3933 | ColumnCount = columnCount, | ||
| 3934 | ColumnNames = columnNames, | 3921 | ColumnNames = columnNames, |
| 3935 | ColumnTypes = columnTypes, | 3922 | Unreal = unreal, |
| 3936 | PrimaryKeys = primaryKeys, | ||
| 3937 | MinValues = minValues, | ||
| 3938 | MaxValues = maxValues, | ||
| 3939 | KeyTables = keyTables, | ||
| 3940 | KeyColumns = keyColumns, | ||
| 3941 | Categories = categories, | ||
| 3942 | Sets = sets, | ||
| 3943 | Descriptions = descriptions, | ||
| 3944 | Modularizations = modularizations, | ||
| 3945 | Unreal = bootstrapperApplicationData, | ||
| 3946 | }); | 3923 | }); |
| 3924 | |||
| 3925 | foreach (var column in columns) | ||
| 3926 | { | ||
| 3927 | this.Core.AddTuple(column); | ||
| 3928 | } | ||
| 3947 | } | 3929 | } |
| 3948 | } | 3930 | } |
| 3949 | } | 3931 | } |
| 3950 | 3932 | ||
| 3933 | private void ParseRow(XElement node, string tableId) | ||
| 3934 | { | ||
| 3935 | var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); | ||
| 3936 | var rowId = Guid.NewGuid().ToString("N").ToUpperInvariant(); | ||
| 3937 | |||
| 3938 | foreach (var attrib in node.Attributes()) | ||
| 3939 | { | ||
| 3940 | this.Core.ParseExtensionAttribute(node, attrib); | ||
| 3941 | } | ||
| 3942 | |||
| 3943 | foreach (var child in node.Elements()) | ||
| 3944 | { | ||
| 3945 | var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); | ||
| 3946 | switch (child.Name.LocalName) | ||
| 3947 | { | ||
| 3948 | case "Data": | ||
| 3949 | string columnName = null; | ||
| 3950 | string data = null; | ||
| 3951 | foreach (var attrib in child.Attributes()) | ||
| 3952 | { | ||
| 3953 | switch (attrib.Name.LocalName) | ||
| 3954 | { | ||
| 3955 | case "Column": | ||
| 3956 | columnName = this.Core.GetAttributeValue(childSourceLineNumbers, attrib); | ||
| 3957 | break; | ||
| 3958 | case "Value": | ||
| 3959 | data = this.Core.GetAttributeValue(childSourceLineNumbers, attrib); | ||
| 3960 | break; | ||
| 3961 | default: | ||
| 3962 | this.Core.ParseExtensionAttribute(child, attrib); | ||
| 3963 | break; | ||
| 3964 | } | ||
| 3965 | } | ||
| 3966 | |||
| 3967 | if (null == columnName) | ||
| 3968 | { | ||
| 3969 | this.Core.Write(ErrorMessages.ExpectedAttribute(childSourceLineNumbers, child.Name.LocalName, "Column")); | ||
| 3970 | } | ||
| 3971 | |||
| 3972 | if (String.IsNullOrEmpty(data)) | ||
| 3973 | { | ||
| 3974 | data = Common.GetInnerText(child); | ||
| 3975 | } | ||
| 3976 | |||
| 3977 | if (!this.Core.EncounteredError) | ||
| 3978 | { | ||
| 3979 | this.Core.AddTuple(new WixCustomTableCellTuple(childSourceLineNumbers, new Identifier(AccessModifier.Private, tableId, rowId, columnName)) | ||
| 3980 | { | ||
| 3981 | RowId = rowId, | ||
| 3982 | ColumnRef = columnName, | ||
| 3983 | TableRef = tableId, | ||
| 3984 | Data = data | ||
| 3985 | }); | ||
| 3986 | } | ||
| 3987 | break; | ||
| 3988 | default: | ||
| 3989 | this.Core.UnexpectedElement(node, child); | ||
| 3990 | break; | ||
| 3991 | } | ||
| 3992 | } | ||
| 3993 | |||
| 3994 | if (!this.Core.EncounteredError) | ||
| 3995 | { | ||
| 3996 | this.Core.CreateSimpleReference(sourceLineNumbers, TupleDefinitions.WixCustomTable, tableId); | ||
| 3997 | } | ||
| 3998 | } | ||
| 3999 | |||
| 3951 | /// <summary> | 4000 | /// <summary> |
| 3952 | /// Parses a directory element. | 4001 | /// Parses a directory element. |
| 3953 | /// </summary> | 4002 | /// </summary> |
