public Column(ColumnCategory category, ColumnType type, string name, object?data = null) { Category = category; Type = type; Name = name; Data = data; }
/// <summary> /// Creates a new column definition. /// </summary> /// <param name="name">Name of column.</param> /// <param name="type">Type of column</param> /// <param name="length">Length of column.</param> /// <param name="primaryKey">If column is primary key.</param> /// <param name="nullable">If column is nullable.</param> /// <param name="modularizeType">Type of modularization for column</param> /// <param name="localizable">If the column is localizable.</param> /// <param name="minValueSet">If the minimum of the value was set.</param> /// <param name="minValue">Minimum value for the column.</param> /// <param name="maxValueSet">If the maximum value was set.</param> /// <param name="maxValue">Maximum value for the colum.</param> /// <param name="keyTable">Optional name of table for foreign key.</param> /// <param name="keyColumnSet">If the key column was set.</param> /// <param name="keyColumn">Optional name of column for foreign key.</param> /// <param name="category">Validation category for column.</param> /// <param name="possibilities">Set of possible values for column.</param> /// <param name="description">Description of column in vaidation table.</param> /// <param name="escapeIdtCharacters">If characters should be escaped in IDT.</param> /// <param name="useCData">If whitespace should be preserved in a CDATA node.</param> public ColumnDefinition(string name, ColumnType type, int length, bool primaryKey, bool nullable, ColumnModularizeType modularizeType, bool localizable, bool minValueSet, int minValue, bool maxValueSet, int maxValue, string keyTable, bool keyColumnSet, int keyColumn, ColumnCategory category, string possibilities, string description, bool escapeIdtCharacters, bool useCData) { this.name = name; this.type = type; this.length = length; this.primaryKey = primaryKey; this.nullable = nullable; this.modularize = modularizeType; this.localizable = localizable; this.minValueSet = minValueSet; this.minValue = minValue; this.maxValueSet = maxValueSet; this.maxValue = maxValue; this.keyTable = keyTable; this.keyColumnSet = keyColumnSet; this.keyColumn = keyColumn; this.category = category; this.possibilities = possibilities; this.description = description; this.escapeIdtCharacters = escapeIdtCharacters; this.useCData = useCData; }
/// <summary> /// Parses a column definition in a table definition. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The ColumnDefintion represented by the Xml.</returns> internal static ColumnDefinition Parse(XmlReader reader) { Debug.Assert("columnDefinition" == reader.LocalName); bool added = false; ColumnCategory category = ColumnCategory.Unknown; string description = null; bool empty = reader.IsEmptyElement; bool escapeIdtCharacters = false; int keyColumn = -1; bool keyColumnSet = false; string keyTable = null; int length = -1; bool localizable = false; int maxValue = 0; bool maxValueSet = false; int minValue = 0; bool minValueSet = false; ColumnModularizeType modularize = ColumnModularizeType.None; string name = null; bool nullable = false; string possibilities = null; bool primaryKey = false; ColumnType type = ColumnType.Unknown; bool useCData = false; // parse the attributes while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "added": added = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "category": switch (reader.Value) { case "anyPath": category = ColumnCategory.AnyPath; break; case "binary": category = ColumnCategory.Binary; break; case "cabinet": category = ColumnCategory.Cabinet; break; case "condition": category = ColumnCategory.Condition; break; case "customSource": category = ColumnCategory.CustomSource; break; case "defaultDir": category = ColumnCategory.DefaultDir; break; case "doubleInteger": category = ColumnCategory.DoubleInteger; break; case "filename": category = ColumnCategory.Filename; break; case "formatted": category = ColumnCategory.Formatted; break; case "formattedSddl": category = ColumnCategory.FormattedSDDLText; break; case "guid": category = ColumnCategory.Guid; break; case "identifier": category = ColumnCategory.Identifier; break; case "integer": category = ColumnCategory.Integer; break; case "language": category = ColumnCategory.Language; break; case "lowerCase": category = ColumnCategory.LowerCase; break; case "path": category = ColumnCategory.Path; break; case "paths": category = ColumnCategory.Paths; break; case "property": category = ColumnCategory.Property; break; case "regPath": category = ColumnCategory.RegPath; break; case "shortcut": category = ColumnCategory.Shortcut; break; case "template": category = ColumnCategory.Template; break; case "text": category = ColumnCategory.Text; break; case "timeDate": category = ColumnCategory.TimeDate; break; case "upperCase": category = ColumnCategory.UpperCase; break; case "version": category = ColumnCategory.Version; break; case "wildCardFilename": category = ColumnCategory.WildCardFilename; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "anyPath", "binary", "cabinet", "condition", "customSource", "defaultDir", "doubleInteger", "filename", "formatted", "formattedSddl", "guid", "identifier", "integer", "language", "lowerCase", "path", "paths", "property", "regPath", "shortcut", "template", "text", "timeDate", "upperCase", "version", "wildCardFilename")); } break; case "description": description = reader.Value; break; case "escapeIdtCharacters": escapeIdtCharacters = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "keyColumn": keyColumnSet = true; keyColumn = Convert.ToInt32(reader.Value, 10); break; case "keyTable": keyTable = reader.Value; break; case "length": length = Convert.ToInt32(reader.Value, 10); break; case "localizable": localizable = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "maxValue": maxValueSet = true; maxValue = Convert.ToInt32(reader.Value, 10); break; case "minValue": minValueSet = true; minValue = Convert.ToInt32(reader.Value, 10); break; case "modularize": switch (reader.Value) { case "column": modularize = ColumnModularizeType.Column; break; case "companionFile": modularize = ColumnModularizeType.CompanionFile; break; case "condition": modularize = ColumnModularizeType.Condition; break; case "controlEventArgument": modularize = ColumnModularizeType.ControlEventArgument; break; case "controlText": modularize = ColumnModularizeType.ControlText; break; case "icon": modularize = ColumnModularizeType.Icon; break; case "none": modularize = ColumnModularizeType.None; break; case "property": modularize = ColumnModularizeType.Property; break; case "semicolonDelimited": modularize = ColumnModularizeType.SemicolonDelimited; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited")); } break; case "name": switch (reader.Value) { case "CREATE": case "DELETE": case "DROP": case "INSERT": throw new WixException(WixErrors.IllegalColumnName(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value)); default: name = reader.Value; break; } break; case "nullable": nullable = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "primaryKey": primaryKey = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; case "set": possibilities = reader.Value; break; case "type": switch (reader.Value) { case "localized": type = ColumnType.Localized; break; case "number": type = ColumnType.Number; break; case "object": type = ColumnType.Object; break; case "string": type = ColumnType.String; break; case "preserved": type = ColumnType.Preserved; break; default: throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "localized", "number", "object", "string")); } break; case "useCData": useCData = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value); break; default: if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal)) { throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name)); } break; } } // parse the child elements (there should be none) if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name)); case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition")); } } ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, modularize, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData); columnDefinition.Added = added; return(columnDefinition); }
/// <summary> /// Parses a column definition in a table definition. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The ColumnDefintion represented by the Xml.</returns> internal static ColumnDefinition Parse(XmlReader reader) { Debug.Assert("columnDefinition" == reader.LocalName); string name = null; ColumnType type = ColumnType.Unknown; int length = -1; bool primaryKey = false; bool symbol = false; bool nullable = false; ColumnModularizeType modularize = ColumnModularizeType.None; bool unreal = false; bool localizable = false; bool minValueSet = false; int minValue = 0; bool maxValueSet = false; int maxValue = 0; string keyTable = null; bool keyColumnSet = false; int keyColumn = -1; ColumnCategory category = ColumnCategory.Unknown; string possibilities = null; string description = null; bool escapeIdtCharacters = false; bool useCData = false; bool empty = reader.IsEmptyElement; // parse the attributes while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "name": name = reader.Value; break; case "type": switch (reader.Value) { case "string": type = ColumnType.String; break; case "localized": type = ColumnType.Localized; break; case "localizedNumber": type = ColumnType.LocalizedNumber; break; case "number": type = ColumnType.Number; break; case "object": type = ColumnType.Object; break; default: throw new WixParseException(String.Format("The columnDefinition/@type attribute contains an unexpected value '{0}'.", reader.Value)); } break; case "length": length = Convert.ToInt32(reader.Value, 10); break; case "primaryKey": primaryKey = Common.IsYes(reader.Value, null, "columnDefinition", "primaryKey", name); break; case "nullable": nullable = Common.IsYes(reader.Value, null, "columnDefinition", "nullable", name); break; case "modularize": switch (reader.Value) { case "none": modularize = ColumnModularizeType.None; break; case "column": modularize = ColumnModularizeType.Column; break; case "companionFile": modularize = ColumnModularizeType.CompanionFile; break; case "condition": modularize = ColumnModularizeType.Condition; break; case "controlEventArgument": modularize = ColumnModularizeType.ControlEventArgument; break; case "icon": modularize = ColumnModularizeType.Icon; break; case "property": modularize = ColumnModularizeType.Property; break; case "semicolonDelimited": modularize = ColumnModularizeType.SemicolonDelimited; break; default: throw new WixParseException(String.Format("The columnDefinition/@modularize attribute contains an unexpected value '{0}'.", reader.Value)); } break; case "symbol": symbol = Common.IsYes(reader.Value, null, "columnDefinition", "symbol", name); break; case "unreal": unreal = Common.IsYes(reader.Value, null, "columnDefinition", "unreal", name); break; case "localizable": localizable = Common.IsYes(reader.Value, null, "columnDefinition", "localizable", name); break; case "minValue": minValueSet = true; minValue = Convert.ToInt32(reader.Value, 10); break; case "maxValue": maxValueSet = true; maxValue = Convert.ToInt32(reader.Value, 10); break; case "keyTable": keyTable = reader.Value; break; case "keyColumn": keyColumnSet = true; keyColumn = Convert.ToInt32(reader.Value, 10); break; case "category": switch (reader.Value) { case "text": category = ColumnCategory.Text; break; case "upperCase": category = ColumnCategory.UpperCase; break; case "lowerCase": category = ColumnCategory.LowerCase; break; case "integer": category = ColumnCategory.Integer; break; case "doubleInteger": category = ColumnCategory.DoubleInteger; break; case "timeDate": category = ColumnCategory.TimeDate; break; case "identifier": category = ColumnCategory.Identifier; break; case "property": category = ColumnCategory.Property; break; case "filename": category = ColumnCategory.Filename; break; case "wildCardFilename": category = ColumnCategory.WildCardFilename; break; case "path": category = ColumnCategory.Path; break; case "paths": category = ColumnCategory.Paths; break; case "anyPath": category = ColumnCategory.AnyPath; break; case "defaultDir": category = ColumnCategory.DefaultDir; break; case "regPath": category = ColumnCategory.RegPath; break; case "formatted": category = ColumnCategory.Formatted; break; case "template": category = ColumnCategory.Template; break; case "condition": category = ColumnCategory.Condition; break; case "guid": category = ColumnCategory.Guid; break; case "version": category = ColumnCategory.Version; break; case "language": category = ColumnCategory.Language; break; case "binary": category = ColumnCategory.Binary; break; case "customSource": category = ColumnCategory.CustomSource; break; case "cabinet": category = ColumnCategory.Cabinet; break; case "shortcut": category = ColumnCategory.Shortcut; break; default: throw new WixParseException(String.Format("The columnDefinition/@category attribute contains an unexpected value '{0}'.", reader.Value)); } break; case "set": possibilities = reader.Value; break; case "description": description = reader.Value; break; case "escapeIdtCharacters": escapeIdtCharacters = Common.IsYes(reader.Value, null, "columnDefinition", reader.LocalName, name); break; case "useCData": useCData = Common.IsYes(reader.Value, null, "columnDefinition", reader.LocalName, name); break; default: throw new WixParseException(String.Format("The columnDefinition element contains an unexpected attribute '{0}'.", reader.Name)); } } // parse the child elements (there should be none) if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixParseException(String.Format("The columnDefinition element contains an unexpected child element {0}.", reader.Name)); case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixParseException("Missing end element while processing the columnDefinition element."); } } return new ColumnDefinition(name, type, length, primaryKey, symbol, nullable, modularize, unreal, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData); }
/// <summary> /// Creates a new column definition. /// </summary> /// <param name="name">Name of column.</param> /// <param name="type">Type of column</param> /// <param name="length">Length of column.</param> /// <param name="primaryKey">If column is primary key.</param> /// <param name="symbol">If column is part of the symbol.</param> /// <param name="nullable">If column is nullable.</param> /// <param name="modularizeType">Type of modularization for column</param> /// <param name="unreal">If column is unreal/virtual.</param> /// <param name="localizable">If the column is localizable.</param> /// <param name="minValueSet">If the minimum of the value was set.</param> /// <param name="minValue">Minimum value for the column.</param> /// <param name="maxValueSet">If the maximum value was set.</param> /// <param name="maxValue">Maximum value for the colum.</param> /// <param name="keyTable">Optional name of table for foreign key.</param> /// <param name="keyColumnSet">If the key column was set.</param> /// <param name="keyColumn">Optional name of column for foreign key.</param> /// <param name="category">Validation category for column.</param> /// <param name="possibilities">Set of possible values for column.</param> /// <param name="description">Description of column in vaidation table.</param> /// <param name="escapeIdtCharacters">If characters should be escaped in IDT.</param> /// <param name="useCData">If whitespace should be preserved in a CDATA node.</param> public ColumnDefinition(string name, ColumnType type, int length, bool primaryKey, bool symbol, bool nullable, ColumnModularizeType modularizeType, bool unreal, bool localizable, bool minValueSet, int minValue, bool maxValueSet, int maxValue, string keyTable, bool keyColumnSet, int keyColumn, ColumnCategory category, string possibilities, string description, bool escapeIdtCharacters, bool useCData) { this.name = name; this.type = type; this.length = length; this.primaryKey = primaryKey; this.symbol = symbol; this.nullable = nullable; this.modularize = modularizeType; this.unreal = unreal; this.localizable = localizable; this.minValueSet = minValueSet; this.minValue = minValue; this.maxValueSet = maxValueSet; this.maxValue = maxValue; this.keyTable = keyTable; this.keyColumnSet = keyColumnSet; this.keyColumn = keyColumn; this.category = category; this.possibilities = possibilities; this.description = description; this.escapeIdtCharacters = escapeIdtCharacters; this.useCData = useCData; }
private static ColumnModularizeType CalculateModularizationType(ColumnModularizeType?modularizeType, ColumnCategory category) { if (modularizeType.HasValue) { return(modularizeType.Value); } switch (category) { case ColumnCategory.Identifier: case ColumnCategory.CustomSource: return(ColumnModularizeType.Column); case ColumnCategory.Condition: return(ColumnModularizeType.Condition); case ColumnCategory.AnyPath: case ColumnCategory.Formatted: case ColumnCategory.FormattedSDDLText: case ColumnCategory.Path: case ColumnCategory.Paths: case ColumnCategory.RegPath: case ColumnCategory.Template: return(ColumnModularizeType.Property); case ColumnCategory.Shortcut: return(ColumnModularizeType.Property); } return(ColumnModularizeType.None); }
/// <summary> /// Creates a new column definition. /// </summary> /// <param name="name">Name of column.</param> /// <param name="type">Type of column</param> /// <param name="length">Length of column.</param> /// <param name="primaryKey">If column is primary key.</param> /// <param name="nullable">If column is nullable.</param> /// <param name="category">Validation category for column.</param> /// <param name="minValue">Optional minimum value for the column.</param> /// <param name="maxValue">Optional maximum value for the colum.</param> /// <param name="keyTable">Optional name of table for foreign key.</param> /// <param name="keyColumn">Optional name of column for foreign key.</param> /// <param name="possibilities">Set of possible values for column.</param> /// <param name="description">Description of column in vaidation table.</param> /// <param name="modularizeType">Type of modularization for column</param> /// <param name="forceLocalizable">If the column is localizable.</param> /// <param name="useCData">If whitespace should be preserved in a CDATA node.</param> public ColumnDefinition(string name, ColumnType type, int length, bool primaryKey, bool nullable, ColumnCategory category, long?minValue = null, long?maxValue = null, string keyTable = null, int?keyColumn = null, string possibilities = null, string description = null, ColumnModularizeType?modularizeType = null, bool forceLocalizable = false, bool useCData = false) { this.Name = name; this.Type = type; this.Length = length; this.PrimaryKey = primaryKey; this.Nullable = nullable; this.ModularizeType = CalculateModularizationType(modularizeType, category); this.IsLocalizable = forceLocalizable || ColumnType.Localized == type; this.MinValue = minValue; this.MaxValue = maxValue; this.KeyTable = keyTable; this.KeyColumn = keyColumn; this.Category = category; this.Possibilities = possibilities; this.Description = description; this.UseCData = useCData; }
/// <summary> /// Parses a column definition in a table definition. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The ColumnDefintion represented by the Xml.</returns> internal static ColumnDefinition Read(XmlReader reader) { if (!reader.LocalName.Equals("columnDefinition")) { throw new XmlException(); } bool added = false; ColumnCategory category = ColumnCategory.Unknown; string description = null; bool empty = reader.IsEmptyElement; int? keyColumn = null; string keyTable = null; int length = -1; bool localizable = false; long? maxValue = null; long? minValue = null; var modularize = ColumnModularizeType.None; string name = null; bool nullable = false; string possibilities = null; bool primaryKey = false; var type = ColumnType.Unknown; bool useCData = false; // parse the attributes while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "added": added = reader.Value.Equals("yes"); break; case "category": switch (reader.Value) { case "anyPath": category = ColumnCategory.AnyPath; break; case "binary": category = ColumnCategory.Binary; break; case "cabinet": category = ColumnCategory.Cabinet; break; case "condition": category = ColumnCategory.Condition; break; case "customSource": category = ColumnCategory.CustomSource; break; case "defaultDir": category = ColumnCategory.DefaultDir; break; case "doubleInteger": category = ColumnCategory.DoubleInteger; break; case "filename": category = ColumnCategory.Filename; break; case "formatted": category = ColumnCategory.Formatted; break; case "formattedSddl": category = ColumnCategory.FormattedSDDLText; break; case "guid": category = ColumnCategory.Guid; break; case "identifier": category = ColumnCategory.Identifier; break; case "integer": category = ColumnCategory.Integer; break; case "language": category = ColumnCategory.Language; break; case "lowerCase": category = ColumnCategory.LowerCase; break; case "path": category = ColumnCategory.Path; break; case "paths": category = ColumnCategory.Paths; break; case "property": category = ColumnCategory.Property; break; case "regPath": category = ColumnCategory.RegPath; break; case "shortcut": category = ColumnCategory.Shortcut; break; case "template": category = ColumnCategory.Template; break; case "text": category = ColumnCategory.Text; break; case "timeDate": category = ColumnCategory.TimeDate; break; case "upperCase": category = ColumnCategory.UpperCase; break; case "version": category = ColumnCategory.Version; break; case "wildCardFilename": category = ColumnCategory.WildCardFilename; break; default: throw new InvalidOperationException(); } break; case "description": description = reader.Value; break; case "keyColumn": keyColumn = Convert.ToInt32(reader.Value, 10); break; case "keyTable": keyTable = reader.Value; break; case "length": length = Convert.ToInt32(reader.Value, 10); break; case "localizable": localizable = reader.Value.Equals("yes"); break; case "maxValue": maxValue = Convert.ToInt32(reader.Value, 10); break; case "minValue": minValue = Convert.ToInt32(reader.Value, 10); break; case "modularize": switch (reader.Value) { case "column": modularize = ColumnModularizeType.Column; break; case "companionFile": modularize = ColumnModularizeType.CompanionFile; break; case "condition": modularize = ColumnModularizeType.Condition; break; case "controlEventArgument": modularize = ColumnModularizeType.ControlEventArgument; break; case "controlText": modularize = ColumnModularizeType.ControlText; break; case "icon": modularize = ColumnModularizeType.Icon; break; case "none": modularize = ColumnModularizeType.None; break; case "property": modularize = ColumnModularizeType.Property; break; case "semicolonDelimited": modularize = ColumnModularizeType.SemicolonDelimited; break; default: throw new XmlException(); } break; case "name": switch (reader.Value) { case "CREATE": case "DELETE": case "DROP": case "INSERT": throw new XmlException(); default: name = reader.Value; break; } break; case "nullable": nullable = reader.Value.Equals("yes"); break; case "primaryKey": primaryKey = reader.Value.Equals("yes"); break; case "set": possibilities = reader.Value; break; case "type": switch (reader.Value) { case "localized": type = ColumnType.Localized; break; case "number": type = ColumnType.Number; break; case "object": type = ColumnType.Object; break; case "string": type = ColumnType.String; break; case "preserved": type = ColumnType.Preserved; break; default: throw new XmlException(); } break; case "useCData": useCData = reader.Value.Equals("yes"); break; } } // parse the child elements (there should be none) if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new XmlException(); case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new XmlException(); } } ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, category, minValue, maxValue, keyTable, keyColumn, possibilities, description, modularize, localizable, useCData); columnDefinition.Added = added; return(columnDefinition); }
public Output Execute() { string modularizationGuid = null; Output output = new Output(new SourceLineNumber(this.DatabasePath)); View validationView = null; // set the output type output.Type = this.OutputType; // get the codepage this.Database.Export("_ForceCodepage", this.IntermediateFolder, "_ForceCodepage.idt"); using (StreamReader sr = File.OpenText(Path.Combine(this.IntermediateFolder, "_ForceCodepage.idt"))) { string line; while (null != (line = sr.ReadLine())) { string[] data = line.Split('\t'); if (2 == data.Length) { output.Codepage = Convert.ToInt32(data[0], CultureInfo.InvariantCulture); } } } // get the summary information table if it exists; it won't if unbinding a transform if (!this.SkipSummaryInfo) { using (SummaryInformation summaryInformation = new SummaryInformation(this.Database)) { Table table = new Table(this.TableDefinitions["_SummaryInformation"]); for (int i = 1; 19 >= i; i++) { string value = summaryInformation.GetProperty(i); if (0 < value.Length) { Row row = table.CreateRow(output.SourceLineNumbers); row[0] = i; row[1] = value; } } output.Tables.Add(table); } } try { // open a view on the validation table if it exists if (this.Database.TableExists("_Validation")) { validationView = this.Database.OpenView("SELECT * FROM `_Validation` WHERE `Table` = ? AND `Column` = ?"); } // get the normal tables using (View tablesView = this.Database.OpenExecuteView("SELECT * FROM _Tables")) { while (true) { using (Record tableRecord = tablesView.Fetch()) { if (null == tableRecord) { break; } string tableName = tableRecord.GetString(1); using (View tableView = this.Database.OpenExecuteView(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM `{0}`", tableName))) { ColumnDefinition[] columns; using (Record columnNameRecord = tableView.GetColumnInfo(MsiInterop.MSICOLINFONAMES), columnTypeRecord = tableView.GetColumnInfo(MsiInterop.MSICOLINFOTYPES)) { // index the primary keys HashSet <string> tablePrimaryKeys = new HashSet <string>(); using (Record primaryKeysRecord = this.Database.PrimaryKeys(tableName)) { int primaryKeysFieldCount = primaryKeysRecord.GetFieldCount(); for (int i = 1; i <= primaryKeysFieldCount; i++) { tablePrimaryKeys.Add(primaryKeysRecord.GetString(i)); } } int columnCount = columnNameRecord.GetFieldCount(); columns = new ColumnDefinition[columnCount]; for (int i = 1; i <= columnCount; i++) { string columnName = columnNameRecord.GetString(i); string idtType = columnTypeRecord.GetString(i); ColumnType columnType; int length; bool nullable; ColumnCategory columnCategory = ColumnCategory.Unknown; ColumnModularizeType columnModularizeType = ColumnModularizeType.None; bool primary = tablePrimaryKeys.Contains(columnName); int? minValue = null; int? maxValue = null; string keyTable = null; int? keyColumn = null; string category = null; string set = null; string description = null; // get the column type, length, and whether its nullable switch (Char.ToLower(idtType[0], CultureInfo.InvariantCulture)) { case 'i': columnType = ColumnType.Number; break; case 'l': columnType = ColumnType.Localized; break; case 's': columnType = ColumnType.String; break; case 'v': columnType = ColumnType.Object; break; default: // TODO: error columnType = ColumnType.Unknown; break; } length = Convert.ToInt32(idtType.Substring(1), CultureInfo.InvariantCulture); nullable = Char.IsUpper(idtType[0]); // try to get validation information if (null != validationView) { using (Record validationRecord = new Record(2)) { validationRecord.SetString(1, tableName); validationRecord.SetString(2, columnName); validationView.Execute(validationRecord); } using (Record validationRecord = validationView.Fetch()) { if (null != validationRecord) { string validationNullable = validationRecord.GetString(3); minValue = validationRecord.IsNull(4) ? null : (int?)validationRecord.GetInteger(4); maxValue = validationRecord.IsNull(5) ? null : (int?)validationRecord.GetInteger(5); keyTable = validationRecord.IsNull(6) ? null : validationRecord.GetString(6); keyColumn = validationRecord.IsNull(7) ? null : (int?)validationRecord.GetInteger(7); category = validationRecord.IsNull(8) ? null : validationRecord.GetString(8); set = validationRecord.IsNull(9) ? null : validationRecord.GetString(9); description = validationRecord.IsNull(10) ? null : validationRecord.GetString(10); // check the validation nullable value against the column definition if (null == validationNullable) { // TODO: warn for illegal validation nullable column } else if ((nullable && "Y" != validationNullable) || (!nullable && "N" != validationNullable)) { // TODO: warn for mismatch between column definition and validation nullable } // convert category to ColumnCategory if (null != category) { try { columnCategory = (ColumnCategory)Enum.Parse(typeof(ColumnCategory), category, true); } catch (ArgumentException) { columnCategory = ColumnCategory.Unknown; } } } else { // TODO: warn about no validation information } } } // guess the modularization type if ("Icon" == keyTable && 1 == keyColumn) { columnModularizeType = ColumnModularizeType.Icon; } else if ("Condition" == columnName) { columnModularizeType = ColumnModularizeType.Condition; } else if (ColumnCategory.Formatted == columnCategory || ColumnCategory.FormattedSDDLText == columnCategory) { columnModularizeType = ColumnModularizeType.Property; } else if (ColumnCategory.Identifier == columnCategory) { columnModularizeType = ColumnModularizeType.Column; } columns[i - 1] = new ColumnDefinition(columnName, columnType, length, primary, nullable, columnCategory, minValue, maxValue, keyTable, keyColumn, set, description, columnModularizeType, (ColumnType.Localized == columnType), true); } } TableDefinition tableDefinition = new TableDefinition(tableName, columns, false, false); // use our table definitions if core properties are the same; this allows us to take advantage // of wix concepts like localizable columns which current code assumes if (this.TableDefinitions.Contains(tableName) && 0 == tableDefinition.CompareTo(this.TableDefinitions[tableName])) { tableDefinition = this.TableDefinitions[tableName]; } Table table = new Table(tableDefinition); while (true) { using (Record rowRecord = tableView.Fetch()) { if (null == rowRecord) { break; } int recordCount = rowRecord.GetFieldCount(); Row row = table.CreateRow(output.SourceLineNumbers); for (int i = 0; recordCount > i && row.Fields.Length > i; i++) { if (rowRecord.IsNull(i + 1)) { if (!row.Fields[i].Column.Nullable) { // TODO: display an error for a null value in a non-nullable field OR // display a warning and put an empty string in the value to let the compiler handle it // (the second option is risky because the later code may make certain assumptions about // the contents of a row value) } } else { switch (row.Fields[i].Column.Type) { case ColumnType.Number: bool success = false; int intValue = rowRecord.GetInteger(i + 1); if (row.Fields[i].Column.IsLocalizable) { success = row.BestEffortSetField(i, Convert.ToString(intValue, CultureInfo.InvariantCulture)); } else { success = row.BestEffortSetField(i, intValue); } if (!success) { this.Messaging.Write(WarningMessages.BadColumnDataIgnored(row.SourceLineNumbers, Convert.ToString(intValue, CultureInfo.InvariantCulture), tableName, row.Fields[i].Column.Name)); } break; case ColumnType.Object: string sourceFile = "FILE NOT EXPORTED, USE THE dark.exe -x OPTION TO EXPORT BINARIES"; if (null != this.ExportBasePath) { string relativeSourceFile = Path.Combine(tableName, row.GetPrimaryKey('.')); sourceFile = Path.Combine(this.ExportBasePath, relativeSourceFile); // ensure the parent directory exists System.IO.Directory.CreateDirectory(Path.Combine(this.ExportBasePath, tableName)); using (FileStream fs = System.IO.File.Create(sourceFile)) { int bytesRead; byte[] buffer = new byte[512]; while (0 != (bytesRead = rowRecord.GetStream(i + 1, buffer, buffer.Length))) { fs.Write(buffer, 0, bytesRead); } } } row[i] = sourceFile; break; default: string value = rowRecord.GetString(i + 1); switch (row.Fields[i].Column.Category) { case ColumnCategory.Guid: value = value.ToUpper(CultureInfo.InvariantCulture); break; } // de-modularize if (!this.SuppressDemodularization && OutputType.Module == output.Type && ColumnModularizeType.None != row.Fields[i].Column.ModularizeType) { Regex modularization = new Regex(@"\.[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}"); if (null == modularizationGuid) { Match match = modularization.Match(value); if (match.Success) { modularizationGuid = String.Concat('{', match.Value.Substring(1).Replace('_', '-'), '}'); } } value = modularization.Replace(value, String.Empty); } // escape "$(" for the preprocessor value = value.Replace("$(", "$$("); // escape things that look like wix variables MatchCollection matches = Common.WixVariableRegex.Matches(value); for (int j = matches.Count - 1; 0 <= j; j--) { value = value.Insert(matches[j].Index, "!"); } row[i] = value; break; } } } } } output.Tables.Add(table); } } } } } finally { if (null != validationView) { validationView.Close(); } } // set the modularization guid as the PackageCode if (null != modularizationGuid) { Table table = output.Tables["_SummaryInformation"]; foreach (Row row in table.Rows) { if (9 == (int)row[0]) // PID_REVNUMBER { row[1] = modularizationGuid; } } } if (this.IsAdminImage) { GenerateWixFileTable(this.DatabasePath, output); GenerateSectionIds(output); } return(output); }
/// <summary> /// Parses a column definition in a table definition. /// </summary> /// <param name="reader">Reader to get data from.</param> /// <returns>The ColumnDefintion represented by the Xml.</returns> internal static ColumnDefinition Parse(XmlReader reader) { Debug.Assert("columnDefinition" == reader.LocalName); string name = null; ColumnType type = ColumnType.Unknown; int length = -1; bool primaryKey = false; bool symbol = false; bool nullable = false; ColumnModularizeType modularize = ColumnModularizeType.None; bool unreal = false; bool localizable = false; bool minValueSet = false; int minValue = 0; bool maxValueSet = false; int maxValue = 0; string keyTable = null; bool keyColumnSet = false; int keyColumn = -1; ColumnCategory category = ColumnCategory.Unknown; string possibilities = null; string description = null; bool escapeIdtCharacters = false; bool useCData = false; bool empty = reader.IsEmptyElement; // parse the attributes while (reader.MoveToNextAttribute()) { switch (reader.LocalName) { case "name": name = reader.Value; break; case "type": switch (reader.Value) { case "string": type = ColumnType.String; break; case "localized": type = ColumnType.Localized; break; case "localizedNumber": type = ColumnType.LocalizedNumber; break; case "number": type = ColumnType.Number; break; case "object": type = ColumnType.Object; break; default: throw new WixParseException(String.Format("The columnDefinition/@type attribute contains an unexpected value '{0}'.", reader.Value)); } break; case "length": length = Convert.ToInt32(reader.Value, 10); break; case "primaryKey": primaryKey = Common.IsYes(reader.Value, null, "columnDefinition", "primaryKey", name); break; case "nullable": nullable = Common.IsYes(reader.Value, null, "columnDefinition", "nullable", name); break; case "modularize": switch (reader.Value) { case "none": modularize = ColumnModularizeType.None; break; case "column": modularize = ColumnModularizeType.Column; break; case "companionFile": modularize = ColumnModularizeType.CompanionFile; break; case "condition": modularize = ColumnModularizeType.Condition; break; case "controlEventArgument": modularize = ColumnModularizeType.ControlEventArgument; break; case "icon": modularize = ColumnModularizeType.Icon; break; case "property": modularize = ColumnModularizeType.Property; break; case "semicolonDelimited": modularize = ColumnModularizeType.SemicolonDelimited; break; default: throw new WixParseException(String.Format("The columnDefinition/@modularize attribute contains an unexpected value '{0}'.", reader.Value)); } break; case "symbol": symbol = Common.IsYes(reader.Value, null, "columnDefinition", "symbol", name); break; case "unreal": unreal = Common.IsYes(reader.Value, null, "columnDefinition", "unreal", name); break; case "localizable": localizable = Common.IsYes(reader.Value, null, "columnDefinition", "localizable", name); break; case "minValue": minValueSet = true; minValue = Convert.ToInt32(reader.Value, 10); break; case "maxValue": maxValueSet = true; maxValue = Convert.ToInt32(reader.Value, 10); break; case "keyTable": keyTable = reader.Value; break; case "keyColumn": keyColumnSet = true; keyColumn = Convert.ToInt32(reader.Value, 10); break; case "category": switch (reader.Value) { case "text": category = ColumnCategory.Text; break; case "upperCase": category = ColumnCategory.UpperCase; break; case "lowerCase": category = ColumnCategory.LowerCase; break; case "integer": category = ColumnCategory.Integer; break; case "doubleInteger": category = ColumnCategory.DoubleInteger; break; case "timeDate": category = ColumnCategory.TimeDate; break; case "identifier": category = ColumnCategory.Identifier; break; case "property": category = ColumnCategory.Property; break; case "filename": category = ColumnCategory.Filename; break; case "wildCardFilename": category = ColumnCategory.WildCardFilename; break; case "path": category = ColumnCategory.Path; break; case "paths": category = ColumnCategory.Paths; break; case "anyPath": category = ColumnCategory.AnyPath; break; case "defaultDir": category = ColumnCategory.DefaultDir; break; case "regPath": category = ColumnCategory.RegPath; break; case "formatted": category = ColumnCategory.Formatted; break; case "template": category = ColumnCategory.Template; break; case "condition": category = ColumnCategory.Condition; break; case "guid": category = ColumnCategory.Guid; break; case "version": category = ColumnCategory.Version; break; case "language": category = ColumnCategory.Language; break; case "binary": category = ColumnCategory.Binary; break; case "customSource": category = ColumnCategory.CustomSource; break; case "cabinet": category = ColumnCategory.Cabinet; break; case "shortcut": category = ColumnCategory.Shortcut; break; default: throw new WixParseException(String.Format("The columnDefinition/@category attribute contains an unexpected value '{0}'.", reader.Value)); } break; case "set": possibilities = reader.Value; break; case "description": description = reader.Value; break; case "escapeIdtCharacters": escapeIdtCharacters = Common.IsYes(reader.Value, null, "columnDefinition", reader.LocalName, name); break; case "useCData": useCData = Common.IsYes(reader.Value, null, "columnDefinition", reader.LocalName, name); break; default: throw new WixParseException(String.Format("The columnDefinition element contains an unexpected attribute '{0}'.", reader.Name)); } } // parse the child elements (there should be none) if (!empty) { bool done = false; while (!done && reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: throw new WixParseException(String.Format("The columnDefinition element contains an unexpected child element {0}.", reader.Name)); case XmlNodeType.EndElement: done = true; break; } } if (!done) { throw new WixParseException("Missing end element while processing the columnDefinition element."); } } return(new ColumnDefinition(name, type, length, primaryKey, symbol, nullable, modularize, unreal, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData)); }
/// <summary> /// Unbind an MSI database file. /// </summary> /// <param name="databaseFile">The database file.</param> /// <param name="database">The opened database.</param> /// <param name="outputType">The type of output to create.</param> /// <param name="exportBasePath">The path where files should be exported.</param> /// <returns>The output representing the database.</returns> private Output UnbindDatabase(string databaseFile, Database database, OutputType outputType, string exportBasePath) { string modularizationGuid = null; Output output = new Output(SourceLineNumberCollection.FromFileName(databaseFile)); View validationView = null; // set the output type output.Type = outputType; // get the codepage database.Export("_ForceCodepage", this.TempFilesLocation, "_ForceCodepage.idt"); using (StreamReader sr = File.OpenText(Path.Combine(this.TempFilesLocation, "_ForceCodepage.idt"))) { string line; while (null != (line = sr.ReadLine())) { string[] data = line.Split('\t'); if (2 == data.Length) { output.Codepage = Convert.ToInt32(data[0], CultureInfo.InvariantCulture); } } } // get the summary information table using (SummaryInformation summaryInformation = new SummaryInformation(database)) { Table table = new Table(null, this.tableDefinitions["_SummaryInformation"]); for (int i = 1; 19 >= i; i++) { string value = summaryInformation.GetProperty(i); if (0 < value.Length) { Row row = table.CreateRow(output.SourceLineNumbers); row[0] = i; row[1] = value; } } output.Tables.Add(table); } try { // open a view on the validation table if it exists if (database.TableExists("_Validation")) { validationView = database.OpenView("SELECT * FROM `_Validation` WHERE `Table` = ? AND `Column` = ?"); } // get the normal tables using (View tablesView = database.OpenExecuteView("SELECT * FROM _Tables")) { Record tableRecord; while (null != (tableRecord = tablesView.Fetch())) { string tableName = tableRecord.GetString(1); using (View tableView = database.OpenExecuteView(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM `{0}`", tableName))) { Record rowRecord; Table table; TableDefinition tableDefinition; if (this.tableDefinitions.Contains(tableName)) { tableDefinition = this.tableDefinitions[tableName]; // TODO: verify table definitions // - error for different column name or data type // - warn for additional columns // - need extra info for new columns in standard tables (MSI 4.0 changes) } else // custom table { TableDefinition customTableDefinition = new TableDefinition(tableName, false, false); Hashtable customTablePrimaryKeys = new Hashtable(); Record customColumnNameRecord = tableView.GetColumnInfo(MsiInterop.MSICOLINFONAMES); Record customColumnTypeRecord = tableView.GetColumnInfo(MsiInterop.MSICOLINFOTYPES); int customColumnCount = customColumnNameRecord.GetFieldCount(); // index the primary keys using (Record primaryKeysRecord = database.PrimaryKeys(tableName)) { int primaryKeysFieldCount = primaryKeysRecord.GetFieldCount(); for (int i = 1; i <= primaryKeysFieldCount; i++) { customTablePrimaryKeys[primaryKeysRecord.GetString(i)] = null; } } for (int i = 1; i <= customColumnCount; i++) { string columnName = customColumnNameRecord.GetString(i); string idtType = customColumnTypeRecord.GetString(i); ColumnType columnType; int length; bool nullable; ColumnCategory columnCategory = ColumnCategory.Unknown; ColumnModularizeType columnModularizeType = ColumnModularizeType.None; bool primary = customTablePrimaryKeys.Contains(columnName); bool minValueSet = false; int minValue = -1; bool maxValueSet = false; int maxValue = -1; string keyTable = null; bool keyColumnSet = false; int keyColumn = -1; string category = null; string set = null; string description = null; // get the column type, length, and whether its nullable switch (Char.ToLower(idtType[0], CultureInfo.InvariantCulture)) { case 'i': columnType = ColumnType.Number; break; case 'l': columnType = ColumnType.Localized; break; case 's': columnType = ColumnType.String; break; case 'v': columnType = ColumnType.Object; break; default: // TODO: error columnType = ColumnType.Unknown; break; } length = Convert.ToInt32(idtType.Substring(1), CultureInfo.InvariantCulture); nullable = Char.IsUpper(idtType[0]); // try to get validation information if (null != validationView) { Record validationRecord = new Record(2); validationRecord.SetString(1, tableName); validationRecord.SetString(2, columnName); validationView.Execute(validationRecord); validationRecord.Close(); if (null != (validationRecord = validationView.Fetch())) { string validationNullable = validationRecord.GetString(3); minValueSet = !validationRecord.IsNull(4); minValue = (minValueSet ? validationRecord.GetInteger(4) : -1); maxValueSet = !validationRecord.IsNull(5); maxValue = (maxValueSet ? validationRecord.GetInteger(5) : -1); keyTable = (!validationRecord.IsNull(6) ? validationRecord.GetString(6) : null); keyColumnSet = !validationRecord.IsNull(7); keyColumn = (keyColumnSet ? validationRecord.GetInteger(7) : -1); category = (!validationRecord.IsNull(8) ? validationRecord.GetString(8) : null); set = (!validationRecord.IsNull(9) ? validationRecord.GetString(9) : null); description = (!validationRecord.IsNull(10) ? validationRecord.GetString(10) : null); // check the validation nullable value against the column definition if (null == validationNullable) { // TODO: warn for illegal validation nullable column } else if ((nullable && "Y" != validationNullable) || (!nullable && "N" != validationNullable)) { // TODO: warn for mismatch between column definition and validation nullable } // convert category to ColumnCategory if (null != category) { try { columnCategory = (ColumnCategory)Enum.Parse(typeof(ColumnCategory), category, true); } catch (ArgumentException) { columnCategory = ColumnCategory.Unknown; } } validationRecord.Close(); } else { // TODO: warn about no validation information } } // guess the modularization type if ("Icon" == keyTable && 1 == keyColumn) { columnModularizeType = ColumnModularizeType.Icon; } else if ("Condition" == columnName) { columnModularizeType = ColumnModularizeType.Condition; } else if (ColumnCategory.Formatted == columnCategory) { columnModularizeType = ColumnModularizeType.Property; } else if (ColumnCategory.Identifier == columnCategory) { columnModularizeType = ColumnModularizeType.Column; } customTableDefinition.Columns.Add(new ColumnDefinition(columnName, columnType, length, primary, nullable, columnModularizeType, (ColumnType.Localized == columnType), minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, columnCategory, set, description, true, true)); } tableDefinition = customTableDefinition; customColumnNameRecord.Close(); customColumnTypeRecord.Close(); } table = new Table(null, tableDefinition); while (null != (rowRecord = tableView.Fetch())) { int recordCount = rowRecord.GetFieldCount(); Row row = table.CreateRow(output.SourceLineNumbers); for (int i = 0; recordCount > i && row.Fields.Length > i; i++) { if (rowRecord.IsNull(i + 1)) { if (!row.Fields[i].Column.IsNullable) { // TODO: display an error for a null value in a non-nullable field OR // display a warning and put an empty string in the value to let the compiler handle it // (the second option is risky because the later code may make certain assumptions about // the contents of a row value) } } else { switch (row.Fields[i].Column.Type) { case ColumnType.Number: if (row.Fields[i].Column.IsLocalizable) { row[i] = Convert.ToString(rowRecord.GetInteger(i + 1), CultureInfo.InvariantCulture); } else { row[i] = rowRecord.GetInteger(i + 1); } break; case ColumnType.Object: string sourceFile = "FILE NOT EXPORTED, USE THE dark.exe -x OPTION TO EXPORT BINARIES"; if (null != exportBasePath) { string relativeSourceFile = Path.Combine(tableName, row.GetPrimaryKey('.')); sourceFile = Path.Combine(exportBasePath, relativeSourceFile); // ensure the parent directory exists System.IO.Directory.CreateDirectory(Path.Combine(exportBasePath, tableName)); using (FileStream fs = System.IO.File.Create(sourceFile)) { int bytesRead; byte[] buffer = new byte[512]; while (0 != (bytesRead = rowRecord.GetStream(i + 1, buffer, buffer.Length))) { fs.Write(buffer, 0, bytesRead); } } } row[i] = sourceFile; break; default: string value = rowRecord.GetString(i + 1); switch (row.Fields[i].Column.Category) { case ColumnCategory.Guid: value = value.ToUpper(CultureInfo.InvariantCulture); break; } // de-modularize if (!this.suppressDemodularization && OutputType.Module == output.Type && ColumnModularizeType.None != row.Fields[i].Column.ModularizeType) { Regex modularization = new Regex(@"\.[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}"); if (null == modularizationGuid) { Match match = modularization.Match(value); if (match.Success) { modularizationGuid = String.Concat('{', match.Value.Substring(1).Replace('_', '-'), '}'); } } value = modularization.Replace(value, String.Empty); } // escape "$(" for the preprocessor value = value.Replace("$(", "$$("); // escape things that look like wix variables MatchCollection matches = Common.WixVariableRegex.Matches(value); for (int j = matches.Count - 1; 0 <= j; j--) { value = value.Insert(matches[j].Index, "!"); } row[i] = value; break; } } } rowRecord.Close(); } output.Tables.Add(table); } tableRecord.Close(); } } } finally { if (null != validationView) { validationView.Close(); } } // set the modularization guid as the PackageCode if (null != modularizationGuid) { Table table = output.Tables["_SummaryInformation"]; foreach (Row row in table.Rows) { if (9 == (int)row[0]) // PID_REVNUMBER { row[1] = modularizationGuid; } } } return(output); }