From 49f1209035aac1fcfad5dbbe25f7b2306d3be86c Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 7 Dec 2017 14:19:05 -0800 Subject: Support MSI backends creating custom tables and remove WixToolset.Data.WindowsInstaller --- src/WixToolset.Data.WindowsInstaller/Table.cs | 435 -------------------------- 1 file changed, 435 deletions(-) delete mode 100644 src/WixToolset.Data.WindowsInstaller/Table.cs (limited to 'src/WixToolset.Data.WindowsInstaller/Table.cs') diff --git a/src/WixToolset.Data.WindowsInstaller/Table.cs b/src/WixToolset.Data.WindowsInstaller/Table.cs deleted file mode 100644 index 4c0df0ad..00000000 --- a/src/WixToolset.Data.WindowsInstaller/Table.cs +++ /dev/null @@ -1,435 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. - -namespace WixToolset.Data -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.IO; - using System.Text; - using System.Xml; - using WixToolset.Data.Rows; - - /// - /// Object that represents a table in a database. - /// - public sealed class Table - { - /// - /// Creates a table in a section. - /// - /// Section to add table to. - /// Definition of the table. - public Table(TableDefinition tableDefinition) - { - this.Definition = tableDefinition; - this.Rows = new List(); - } - - /// - /// Gets the table definition. - /// - /// Definition of the table. - public TableDefinition Definition { get; private set; } - - /// - /// Gets the name of the table. - /// - /// Name of the table. - public string Name - { - get { return this.Definition.Name; } - } - - /// - /// Gets or sets the table transform operation. - /// - /// The table transform operation. - public TableOperation Operation { get; set; } - - /// - /// Gets the rows contained in the table. - /// - /// Rows contained in the table. - public IList Rows { get; private set; } - - /// - /// Creates a new row in the table. - /// - /// Original source lines for this row. - /// Specifies whether to only create the row or add it to the table automatically. - /// Row created in table. - public Row CreateRow(SourceLineNumber sourceLineNumbers, bool add = true) - { - Row row; - - switch (this.Name) - { - case "BBControl": - row = new BBControlRow(sourceLineNumbers, this); - break; - case "WixBundlePackage": - row = new WixBundlePackageRow(sourceLineNumbers, this); - break; - case "WixBundleExePackage": - row = new WixBundleExePackageRow(sourceLineNumbers, this); - break; - case "WixBundleMsiPackage": - row = new WixBundleMsiPackageRow(sourceLineNumbers, this); - break; - case "WixBundleMspPackage": - row = new WixBundleMspPackageRow(sourceLineNumbers, this); - break; - case "WixBundleMsuPackage": - row = new WixBundleMsuPackageRow(sourceLineNumbers, this); - break; - case "Component": - row = new ComponentRow(sourceLineNumbers, this); - break; - case "WixBundleContainer": - row = new WixBundleContainerRow(sourceLineNumbers, this); - break; - case "Control": - row = new ControlRow(sourceLineNumbers, this); - break; - case "File": - row = new FileRow(sourceLineNumbers, this); - break; - case "WixBundleMsiFeature": - row = new WixBundleMsiFeatureRow(sourceLineNumbers, this); - break; - case "WixBundleMsiProperty": - row = new WixBundleMsiPropertyRow(sourceLineNumbers, this); - break; - case "Media": - row = new MediaRow(sourceLineNumbers, this); - break; - case "WixBundlePayload": - row = new WixBundlePayloadRow(sourceLineNumbers, this); - break; - case "Property": - row = new PropertyRow(sourceLineNumbers, this); - break; - case "WixRelatedBundle": - row = new WixRelatedBundleRow(sourceLineNumbers, this); - break; - case "WixBundleRelatedPackage": - row = new WixBundleRelatedPackageRow(sourceLineNumbers, this); - break; - case "WixBundleRollbackBoundary": - row = new WixBundleRollbackBoundaryRow(sourceLineNumbers, this); - break; - case "Upgrade": - row = new UpgradeRow(sourceLineNumbers, this); - break; - case "WixBundleVariable": - row = new WixBundleVariableRow(sourceLineNumbers, this); - break; - case "WixAction": - row = new WixActionRow(sourceLineNumbers, this); - break; - case "WixApprovedExeForElevation": - row = new WixApprovedExeForElevationRow(sourceLineNumbers, this); - break; - case "WixBundle": - row = new WixBundleRow(sourceLineNumbers, this); - break; - case "WixBundlePackageExitCode": - row = new WixBundlePackageExitCodeRow(sourceLineNumbers, this); - break; - case "WixBundlePatchTargetCode": - row = new WixBundlePatchTargetCodeRow(sourceLineNumbers, this); - break; - case "WixBundleSlipstreamMsp": - row = new WixBundleSlipstreamMspRow(sourceLineNumbers, this); - break; - case "WixBundleUpdate": - row = new WixBundleUpdateRow(sourceLineNumbers, this); - break; - case "WixBundleCatalog": - row = new WixBundleCatalogRow(sourceLineNumbers, this); - break; - case "WixChain": - row = new WixChainRow(sourceLineNumbers, this); - break; - case "WixChainItem": - row = new WixChainItemRow(sourceLineNumbers, this); - break; - case "WixBundlePackageCommandLine": - row = new WixBundlePackageCommandLineRow(sourceLineNumbers, this); - break; - case "WixComplexReference": - row = new WixComplexReferenceRow(sourceLineNumbers, this); - break; - case "WixDeltaPatchFile": - row = new WixDeltaPatchFileRow(sourceLineNumbers, this); - break; - case "WixDeltaPatchSymbolPaths": - row = new WixDeltaPatchSymbolPathsRow(sourceLineNumbers, this); - break; - case "WixFile": - row = new WixFileRow(sourceLineNumbers, this); - break; - case "WixGroup": - row = new WixGroupRow(sourceLineNumbers, this); - break; - case "WixMedia": - row = new WixMediaRow(sourceLineNumbers, this); - break; - case "WixMediaTemplate": - row = new WixMediaTemplateRow(sourceLineNumbers, this); - break; - case "WixMerge": - row = new WixMergeRow(sourceLineNumbers, this); - break; - case "WixPayloadProperties": - row = new WixPayloadPropertiesRow(sourceLineNumbers, this); - break; - case "WixProperty": - row = new WixPropertyRow(sourceLineNumbers, this); - break; - case "WixSimpleReference": - row = new WixSimpleReferenceRow(sourceLineNumbers, this); - break; - case "WixUpdateRegistration": - row = new WixUpdateRegistrationRow(sourceLineNumbers, this); - break; - - default: - row = new Row(sourceLineNumbers, this); - break; - } - - if (add) - { - this.Rows.Add(row); - } - - return row; - } - - /// - /// Parse a table from the xml. - /// - /// XmlReader where the intermediate is persisted. - /// Section to populate with persisted data. - /// TableDefinitions to use in the intermediate. - /// The parsed table. - internal static Table Read(XmlReader reader, TableDefinitionCollection tableDefinitions) - { - Debug.Assert("table" == reader.LocalName); - - bool empty = reader.IsEmptyElement; - TableOperation operation = TableOperation.None; - string name = null; - - while (reader.MoveToNextAttribute()) - { - switch (reader.LocalName) - { - case "name": - name = reader.Value; - break; - case "op": - switch (reader.Value) - { - case "add": - operation = TableOperation.Add; - break; - case "drop": - operation = TableOperation.Drop; - break; - default: - throw new XmlException(); - } - break; - } - } - - if (null == name) - { - throw new XmlException(); - } - - TableDefinition tableDefinition = tableDefinitions[name]; - Table table = new Table(tableDefinition); - table.Operation = operation; - - if (!empty) - { - bool done = false; - - // loop through all the rows in a table - while (!done && reader.Read()) - { - switch (reader.NodeType) - { - case XmlNodeType.Element: - switch (reader.LocalName) - { - case "row": - Row.Read(reader, table); - break; - default: - throw new XmlException(); - } - break; - case XmlNodeType.EndElement: - done = true; - break; - } - } - - if (!done) - { - throw new XmlException(); - } - } - - return table; - } - - /// - /// Modularize the table. - /// - /// String containing the GUID of the Merge Module, if appropriate. - /// Optional collection of identifiers that should not be modularized. - public void Modularize(string modularizationGuid, ISet suppressModularizationIdentifiers) - { - List modularizedColumns = new List(); - - // find the modularized columns - for (int i = 0; i < this.Definition.Columns.Count; i++) - { - if (ColumnModularizeType.None != this.Definition.Columns[i].ModularizeType) - { - modularizedColumns.Add(i); - } - } - - if (0 < modularizedColumns.Count) - { - foreach (Row row in this.Rows) - { - foreach (int modularizedColumn in modularizedColumns) - { - Field field = row.Fields[modularizedColumn]; - - if (null != field.Data) - { - field.Data = row.GetModularizedValue(field, modularizationGuid, suppressModularizationIdentifiers); - } - } - } - } - } - - /// - /// Persists a row in an XML format. - /// - /// XmlWriter where the Row should persist itself as XML. - [SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase", Justification = "Changing the way this string normalizes would result " + - "in a change to the way the intermediate files are generated, potentially causing extra churn in patches on an MSI built from an older version of WiX. " + - "Furthermore, there is no security hole here, as the strings won't need to make a round trip")] - internal void Write(XmlWriter writer) - { - if (null == writer) - { - throw new ArgumentNullException("writer"); - } - - writer.WriteStartElement("table", Intermediate.XmlNamespaceUri); - writer.WriteAttributeString("name", this.Name); - - if (TableOperation.None != this.Operation) - { - writer.WriteAttributeString("op", this.Operation.ToString().ToLowerInvariant()); - } - - foreach (Row row in this.Rows) - { - row.Write(writer); - } - - writer.WriteEndElement(); - } - - /// - /// Writes the table in IDT format to the provided stream. - /// - /// Stream to write the table to. - /// Whether to keep columns added in a transform. - public void ToIdtDefinition(StreamWriter writer, bool keepAddedColumns) - { - if (this.Definition.Unreal) - { - return; - } - - if (TableDefinition.MaxColumnsInRealTable < this.Definition.Columns.Count) - { - throw new WixException(WixDataErrors.TooManyColumnsInRealTable(this.Definition.Name, this.Definition.Columns.Count, TableDefinition.MaxColumnsInRealTable)); - } - - // Tack on the table header, and flush before we start writing bytes directly to the stream. - writer.Write(this.Definition.ToIdtDefinition(keepAddedColumns)); - writer.Flush(); - - using (var binary = new BinaryWriter(writer.BaseStream, writer.Encoding, true)) - { - // Create an encoding that replaces characters with question marks, and doesn't throw. We'll - // use this in case of errors - Encoding convertEncoding = Encoding.GetEncoding(writer.Encoding.CodePage); - - foreach (Row row in this.Rows) - { - if (row.Redundant) - { - continue; - } - - string rowString = row.ToIdtDefinition(keepAddedColumns); - byte[] rowBytes; - - try - { - // GetBytes will throw an exception if any character doesn't match our current encoding - rowBytes = writer.Encoding.GetBytes(rowString); - } - catch (EncoderFallbackException) - { - Messaging.Instance.OnMessage(WixDataErrors.InvalidStringForCodepage(row.SourceLineNumbers, Convert.ToString(writer.Encoding.WindowsCodePage, CultureInfo.InvariantCulture))); - - rowBytes = convertEncoding.GetBytes(rowString); - } - - binary.Write(rowBytes, 0, rowBytes.Length); - } - } - } - - /// - /// Validates the rows of this OutputTable and throws if it collides on - /// primary keys. - /// - public void ValidateRows() - { - Dictionary primaryKeys = new Dictionary(); - - foreach (Row row in this.Rows) - { - string primaryKey = row.GetPrimaryKey(); - - SourceLineNumber collisionSourceLineNumber; - if (primaryKeys.TryGetValue(primaryKey, out collisionSourceLineNumber)) - { - throw new WixException(WixDataErrors.DuplicatePrimaryKey(collisionSourceLineNumber, primaryKey, this.Definition.Name)); - } - - primaryKeys.Add(primaryKey, row.SourceLineNumbers); - } - } - } -} -- cgit v1.2.3-55-g6feb