/// <summary> /// Parses a sql database element /// </summary> /// <param name="node">Element to parse.</param> /// <param name="componentId">Identifier for parent component.</param> private void ParseSqlDatabaseElement(XElement node, string componentId) { SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string id = null; int attributes = 0; string database = null; string fileSpec = null; string instance = null; string logFileSpec = null; string server = null; string user = null; foreach (XAttribute attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "ConfirmOverwrite": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbConfirmOverwrite; } break; case "ContinueOnError": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbContinueOnError; } break; case "CreateOnInstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbCreateOnInstall; } break; case "CreateOnReinstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbCreateOnReinstall; } break; case "CreateOnUninstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbCreateOnUninstall; } break; case "Database": database = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "DropOnInstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbDropOnInstall; } break; case "DropOnReinstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbDropOnReinstall; } break; case "DropOnUninstall": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName)); } if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= DbDropOnUninstall; } break; case "Instance": instance = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "Server": server = this.Core.GetAttributeValue(sourceLineNumbers, attrib); break; case "User": user = this.Core.GetAttributeValue(sourceLineNumbers, attrib); if (!CompilerCore.ContainsProperty(user)) { user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "User", user); } break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } if (null == id) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); } if (null == database) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Database")); } else if (128 < database.Length) { this.Core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Database", database, 128)); } if (null == server) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Server")); } if (0 == attributes && null != componentId) { this.Core.OnMessage(SqlErrors.OneOfAttributesRequiredUnderComponent(sourceLineNumbers, node.Name.LocalName, "CreateOnInstall", "CreateOnUninstall", "DropOnInstall", "DropOnUninstall")); } foreach (XElement child in node.Elements()) { if (this.Namespace == child.Name.Namespace) { SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child); switch (child.Name.LocalName) { case "SqlScript": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } this.ParseSqlScriptElement(child, componentId, id); break; case "SqlString": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } this.ParseSqlStringElement(child, componentId, id); break; case "SqlFileSpec": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } else if (null != fileSpec) { this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, 1)); } fileSpec = this.ParseSqlFileSpecElement(child); break; case "SqlLogFileSpec": if (null == componentId) { this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName)); } else if (null != logFileSpec) { this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, 1)); } logFileSpec = this.ParseSqlFileSpecElement(child); break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.ParseExtensionElement(node, child); } } if (null != componentId) { // Reference InstallSqlData and UninstallSqlData since nothing will happen without it this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "InstallSqlData"); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "UninstallSqlData"); } if (!this.Core.EncounteredError) { Row row = this.Core.CreateRow(sourceLineNumbers, "SqlDatabase"); row[0] = id; row[1] = server; row[2] = instance; row[3] = database; row[4] = componentId; row[5] = user; row[6] = fileSpec; row[7] = logFileSpec; if (0 != attributes) { row[8] = attributes; } } }
/// <summary> /// Parses a sql script element. /// </summary> /// <param name="node">Element to parse.</param> /// <param name="componentId">Identifier for parent component.</param> /// <param name="sqlDb">Optional database to execute script against.</param> private void ParseSqlScriptElement(XmlNode node, string componentId, string sqlDb) { SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); string id = null; int attributes = 0; bool rollbackAttribute = false; bool nonRollbackAttribute = false; string binary = null; int sequence = CompilerCore.IntegerNotSet; string user = null; foreach (XmlAttribute attrib in node.Attributes) { if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == this.schema.TargetNamespace) { switch (attrib.LocalName) { case "Id": id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); break; case "BinaryKey": binary = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "Binary", binary); break; case "Sequence": sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); break; case "SqlDb": if (null != sqlDb) { this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name, attrib.Name, node.ParentNode.Name)); } sqlDb = this.Core.GetAttributeValue(sourceLineNumbers, attrib); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "SqlDatabase", sqlDb); break; case "User": user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "User", user); break; // Flag-setting attributes case "ContinueOnError": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlContinueOnError; } break; case "ExecuteOnInstall": if (rollbackAttribute) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name, attrib.Name, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); } nonRollbackAttribute = true; if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlExecuteOnInstall; } break; case "ExecuteOnReinstall": if (rollbackAttribute) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name, attrib.Name, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); } nonRollbackAttribute = true; if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlExecuteOnReinstall; } break; case "ExecuteOnUninstall": if (rollbackAttribute) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name, attrib.Name, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); } nonRollbackAttribute = true; if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlExecuteOnUninstall; } break; case "RollbackOnInstall": if (nonRollbackAttribute) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name, attrib.Name, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); } rollbackAttribute = true; if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlExecuteOnInstall; attributes |= SqlRollback; } break; case "RollbackOnReinstall": if (nonRollbackAttribute) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name, attrib.Name, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); } rollbackAttribute = true; if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlExecuteOnReinstall; attributes |= SqlRollback; } break; case "RollbackOnUninstall": if (nonRollbackAttribute) { this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name, attrib.Name, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); } rollbackAttribute = true; if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= SqlExecuteOnUninstall; attributes |= SqlRollback; } break; default: this.Core.UnexpectedAttribute(sourceLineNumbers, attrib); break; } } else { this.Core.UnsupportedExtensionAttribute(sourceLineNumbers, attrib); } } if (null == id) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "Id")); } if (null == binary) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "BinaryKey")); } if (null == sqlDb) { this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name, "SqlDb")); } if (0 == attributes) { this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); } foreach (XmlNode child in node.ChildNodes) { if (XmlNodeType.Element == child.NodeType) { if (child.NamespaceURI == this.schema.TargetNamespace) { this.Core.UnexpectedElement(node, child); } else { switch (child.LocalName) { case "Binary": this.Core.OnMessage(SqlErrors.DeprecatedBinaryChildElement(sourceLineNumbers, node.Name)); break; default: this.Core.UnsupportedExtensionElement(node, child); break; } } } } // Reference InstallSqlData and UninstallSqlData since nothing will happen without it this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "InstallSqlData"); this.Core.CreateWixSimpleReferenceRow(sourceLineNumbers, "CustomAction", "UninstallSqlData"); if (!this.Core.EncounteredError) { Row row = this.Core.CreateRow(sourceLineNumbers, "SqlScript"); row[0] = id; row[1] = sqlDb; row[2] = componentId; row[3] = binary; row[4] = user; row[5] = attributes; if (CompilerCore.IntegerNotSet != sequence) { row[6] = sequence; } } }