예제 #1
0
 public Column(ColumnCategory category, ColumnType type, string name, object?data = null)
 {
     Category = category;
     Type     = type;
     Name     = name;
     Data     = data;
 }
예제 #2
0
 /// <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;
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
 /// <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;
 }
예제 #6
0
        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);
        }
예제 #7
0
 /// <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;
 }
예제 #8
0
        /// <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);
        }
예제 #9
0
        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);
        }
예제 #10
0
        /// <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));
        }
예제 #11
0
        /// <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);
        }