From 8464662dfcf3a6e4fafc33440b33236773d96a65 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sat, 15 Dec 2018 22:40:06 -0600 Subject: Import code from old v4 repo --- src/wixext/SqlCompiler.cs | 793 +++++++++++++++++++++++++++++++++++++++++ src/wixext/SqlDecompiler.cs | 512 ++++++++++++++++++++++++++ src/wixext/SqlErrors.cs | 32 ++ src/wixext/SqlExtensionData.cs | 64 ++++ src/wixext/sql.xsd | 342 ++++++++++++++++++ src/wixext/tables.xml | 73 ++++ src/wixlib/SqlExtension.wxs | 46 +++ src/wixlib/de-de.wxl | 17 + src/wixlib/en-us.wxl | 17 + src/wixlib/es-es.wxl | 18 + src/wixlib/ja-jp.wxl | 17 + src/wixlib/pl-pl.wxl | 17 + src/wixlib/pt-br.wxl | 17 + src/wixlib/pt-pt.wxl | 17 + 14 files changed, 1982 insertions(+) create mode 100644 src/wixext/SqlCompiler.cs create mode 100644 src/wixext/SqlDecompiler.cs create mode 100644 src/wixext/SqlErrors.cs create mode 100644 src/wixext/SqlExtensionData.cs create mode 100644 src/wixext/sql.xsd create mode 100644 src/wixext/tables.xml create mode 100644 src/wixlib/SqlExtension.wxs create mode 100644 src/wixlib/de-de.wxl create mode 100644 src/wixlib/en-us.wxl create mode 100644 src/wixlib/es-es.wxl create mode 100644 src/wixlib/ja-jp.wxl create mode 100644 src/wixlib/pl-pl.wxl create mode 100644 src/wixlib/pt-br.wxl create mode 100644 src/wixlib/pt-pt.wxl diff --git a/src/wixext/SqlCompiler.cs b/src/wixext/SqlCompiler.cs new file mode 100644 index 00000000..eecfbba0 --- /dev/null +++ b/src/wixext/SqlCompiler.cs @@ -0,0 +1,793 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensions +{ + using System; + using System.Collections.Generic; + using System.Xml.Linq; + using WixToolset.Data; + using WixToolset.Extensibility; + + /// + /// The compiler for the WiX Toolset SQL Server Extension. + /// + public sealed class SqlCompiler : CompilerExtension + { + // sql database attributes definitions (from sca.h) + internal const int DbCreateOnInstall = 0x00000001; + internal const int DbDropOnUninstall = 0x00000002; + internal const int DbContinueOnError = 0x00000004; + internal const int DbDropOnInstall = 0x00000008; + internal const int DbCreateOnUninstall = 0x00000010; + internal const int DbConfirmOverwrite = 0x00000020; + internal const int DbCreateOnReinstall = 0x00000040; + internal const int DbDropOnReinstall = 0x00000080; + + // sql string/script attributes definitions (from sca.h) + internal const int SqlExecuteOnInstall = 0x00000001; + internal const int SqlExecuteOnUninstall = 0x00000002; + internal const int SqlContinueOnError = 0x00000004; + internal const int SqlRollback = 0x00000008; + internal const int SqlExecuteOnReinstall = 0x00000010; + + /// + /// Instantiate a new SqlCompiler. + /// + public SqlCompiler() + { + this.Namespace = "http://wixtoolset.org/schemas/v4/wxs/sql"; + } + + /// + /// Processes an element for the Compiler. + /// + /// Source line number for the parent element. + /// Parent element of element to process. + /// Element to process. + /// Extra information about the context in which this element is being parsed. + public override void ParseElement(XElement parentElement, XElement element, IDictionary context) + { + switch (parentElement.Name.LocalName) + { + case "Component": + string componentId = context["ComponentId"]; + string directoryId = context["DirectoryId"]; + + switch (element.Name.LocalName) + { + case "SqlDatabase": + this.ParseSqlDatabaseElement(element, componentId); + break; + case "SqlScript": + this.ParseSqlScriptElement(element, componentId, null); + break; + case "SqlString": + this.ParseSqlStringElement(element, componentId, null); + break; + default: + this.Core.UnexpectedElement(parentElement, element); + break; + } + break; + case "Fragment": + case "Module": + case "Product": + switch (element.Name.LocalName) + { + case "SqlDatabase": + this.ParseSqlDatabaseElement(element, null); + break; + default: + this.Core.UnexpectedElement(parentElement, element); + break; + } + break; + default: + this.Core.UnexpectedElement(parentElement, element); + break; + } + } + + /// + /// Parses a sql database element + /// + /// Element to parse. + /// Identifier for parent component. + 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 (!this.Core.ContainsProperty(user)) + { + user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.Core.CreateSimpleReference(sourceLineNumbers, "User", user); + } + break; + default: + this.Core.UnexpectedAttribute(node, 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.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallSqlData"); + this.Core.CreateSimpleReference(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; + } + } + } + + /// + /// Parses a sql file specification element. + /// + /// Element to parse. + /// Identifier of sql file specification. + private string ParseSqlFileSpecElement(XElement node) + { + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); + string id = null; + string fileName = null; + string growthSize = null; + string maxSize = null; + string name = null; + string size = 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 "Name": + name = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Filename": + fileName = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "Size": + size = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "MaxSize": + maxSize = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "GrowthSize": + growthSize = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + break; + default: + this.Core.UnexpectedAttribute(node, attrib); + break; + } + } + else + { + this.Core.ParseExtensionAttribute(node, attrib); + } + } + + if (null == id) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); + } + + if (null == name) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name")); + } + + if (null == fileName) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Filename")); + } + + this.Core.ParseForExtensionElements(node); + + if (!this.Core.EncounteredError) + { + Row row = this.Core.CreateRow(sourceLineNumbers, "SqlFileSpec"); + row[0] = id; + row[1] = name; + row[2] = fileName; + if (null != size) + { + row[3] = size; + } + + if (null != maxSize) + { + row[4] = maxSize; + } + + if (null != growthSize) + { + row[5] = growthSize; + } + } + + return id; + } + + /// + /// Parses a sql script element. + /// + /// Element to parse. + /// Identifier for parent component. + /// Optional database to execute script against. + private void ParseSqlScriptElement(XElement node, string componentId, string sqlDb) + { + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); + string id = null; + int attributes = 0; + bool rollbackAttribute = false; + bool nonRollbackAttribute = false; + string binary = null; + int sequence = CompilerConstants.IntegerNotSet; + 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 "BinaryKey": + binary = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.Core.CreateSimpleReference(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.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName)); + } + sqlDb = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + this.Core.CreateSimpleReference(sourceLineNumbers, "SqlDatabase", sqlDb); + break; + case "User": + user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.Core.CreateSimpleReference(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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnUninstall; + attributes |= SqlRollback; + } + break; + default: + this.Core.UnexpectedAttribute(node, attrib); + break; + } + } + else + { + this.Core.ParseExtensionAttribute(node, attrib); + } + } + + if (null == id) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); + } + + if (null == binary) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "BinaryKey")); + } + + if (null == sqlDb) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SqlDb")); + } + + if (0 == attributes) + { + this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + + this.Core.ParseForExtensionElements(node); + + // Reference InstallSqlData and UninstallSqlData since nothing will happen without it + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallSqlData"); + this.Core.CreateSimpleReference(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 (CompilerConstants.IntegerNotSet != sequence) + { + row[6] = sequence; + } + } + } + + /// + /// Parses a sql string element. + /// + /// Element to parse. + /// Identifier for parent component. + /// Optional database to execute string against. + private void ParseSqlStringElement(XElement node, string componentId, string sqlDb) + { + SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); + string id = null; + int attributes = 0; + bool rollbackAttribute = false; + bool nonRollbackAttribute = false; + int sequence = CompilerConstants.IntegerNotSet; + string sql = 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 "ContinueOnError": + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlContinueOnError; + } + break; + case "ExecuteOnInstall": + if (rollbackAttribute) + { + this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "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.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall")); + } + rollbackAttribute = true; + + if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) + { + attributes |= SqlExecuteOnUninstall; + attributes |= SqlRollback; + } + break; + case "Sequence": + sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue); + break; + case "SQL": + sql = this.Core.GetAttributeValue(sourceLineNumbers, attrib); + break; + case "SqlDb": + if (null != sqlDb) + { + this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "SqlDb", "SqlDatabase")); + } + + sqlDb = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.Core.CreateSimpleReference(sourceLineNumbers, "SqlDatabase", sqlDb); + break; + case "User": + user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib); + this.Core.CreateSimpleReference(sourceLineNumbers, "User", user); + break; + default: + this.Core.UnexpectedAttribute(node, attrib); + break; + } + } + else + { + this.Core.ParseExtensionAttribute(node, attrib); + } + } + + if (null == id) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); + } + + if (null == sql) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SQL")); + } + + if (null == sqlDb) + { + this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SqlDb")); + } + + if (0 == attributes) + { + this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall")); + } + + this.Core.ParseForExtensionElements(node); + + // Reference InstallSqlData and UninstallSqlData since nothing will happen without it + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallSqlData"); + this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "UninstallSqlData"); + + if (!this.Core.EncounteredError) + { + Row row = this.Core.CreateRow(sourceLineNumbers, "SqlString"); + row[0] = id; + row[1] = sqlDb; + row[2] = componentId; + row[3] = sql; + row[4] = user; + row[5] = attributes; + if (CompilerConstants.IntegerNotSet != sequence) + { + row[6] = sequence; + } + } + } + } +} diff --git a/src/wixext/SqlDecompiler.cs b/src/wixext/SqlDecompiler.cs new file mode 100644 index 00000000..64192e84 --- /dev/null +++ b/src/wixext/SqlDecompiler.cs @@ -0,0 +1,512 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensions +{ + using System.Collections; + using WixToolset.Data; + using WixToolset.Extensibility; + using Sql = WixToolset.Extensions.Serialize.Sql; + using Wix = WixToolset.Data.Serialize; + + /// + /// The decompiler for the WiX Toolset SQL Server Extension. + /// + public sealed class SqlDecompiler : DecompilerExtension + { + /// + /// Creates a decompiler for SQL Extension. + /// + public SqlDecompiler() + { + this.TableDefinitions = SqlExtensionData.GetExtensionTableDefinitions(); + } + + /// + /// Get the extensions library to be removed. + /// + /// Table definitions for library. + /// Library to remove from decompiled output. + public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions) + { + return SqlExtensionData.GetExtensionLibrary(tableDefinitions); + } + + /// + /// Decompiles an extension table. + /// + /// The table to decompile. + public override void DecompileTable(Table table) + { + switch (table.Name) + { + case "SqlDatabase": + this.DecompileSqlDatabaseTable(table); + break; + case "SqlFileSpec": + // handled in FinalizeSqlFileSpecTable + break; + case "SqlScript": + this.DecompileSqlScriptTable(table); + break; + case "SqlString": + this.DecompileSqlStringTable(table); + break; + default: + base.DecompileTable(table); + break; + } + } + + /// + /// Finalize decompilation. + /// + /// The collection of all tables. + public override void Finish(TableIndexedCollection tables) + { + this.FinalizeSqlFileSpecTable(tables); + this.FinalizeSqlScriptAndSqlStringTables(tables); + } + + /// + /// Decompile the SqlDatabase table. + /// + /// The table to decompile. + private void DecompileSqlDatabaseTable(Table table) + { + foreach (Row row in table.Rows) + { + Sql.SqlDatabase sqlDatabase = new Sql.SqlDatabase(); + + sqlDatabase.Id = (string)row[0]; + + if (null != row[1]) + { + sqlDatabase.Server = (string)row[1]; + } + + if (null != row[2]) + { + sqlDatabase.Instance = (string)row[2]; + } + + sqlDatabase.Database = (string)row[3]; + + if (null != row[5]) + { + sqlDatabase.User = (string)row[5]; + } + + // the FileSpec_ and FileSpec_Log columns will be handled in FinalizeSqlFileSpecTable + + if (null != row[8]) + { + int attributes = (int)row[8]; + + if (SqlCompiler.DbCreateOnInstall == (attributes & SqlCompiler.DbCreateOnInstall)) + { + sqlDatabase.CreateOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbDropOnUninstall == (attributes & SqlCompiler.DbDropOnUninstall)) + { + sqlDatabase.DropOnUninstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbContinueOnError == (attributes & SqlCompiler.DbContinueOnError)) + { + sqlDatabase.ContinueOnError = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbDropOnInstall == (attributes & SqlCompiler.DbDropOnInstall)) + { + sqlDatabase.DropOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbCreateOnUninstall == (attributes & SqlCompiler.DbCreateOnUninstall)) + { + sqlDatabase.CreateOnUninstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbConfirmOverwrite == (attributes & SqlCompiler.DbConfirmOverwrite)) + { + sqlDatabase.ConfirmOverwrite = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbCreateOnReinstall == (attributes & SqlCompiler.DbCreateOnReinstall)) + { + sqlDatabase.CreateOnReinstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.DbDropOnReinstall == (attributes & SqlCompiler.DbDropOnReinstall)) + { + sqlDatabase.DropOnReinstall = Sql.YesNoType.yes; + } + } + + if (null != row[4]) + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[4]); + + if (null != component) + { + component.AddChild(sqlDatabase); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[4], "Component")); + } + } + else + { + this.Core.RootElement.AddChild(sqlDatabase); + } + this.Core.IndexElement(row, sqlDatabase); + } + } + + /// + /// Decompile the SqlScript table. + /// + /// The table to decompile. + private void DecompileSqlScriptTable(Table table) + { + foreach (Row row in table.Rows) + { + Sql.SqlScript sqlScript = new Sql.SqlScript(); + + sqlScript.Id = (string)row[0]; + + // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables + + sqlScript.BinaryKey = (string)row[3]; + + if (null != row[4]) + { + sqlScript.User = (string)row[4]; + } + + int attributes = (int)row[5]; + + if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError)) + { + sqlScript.ContinueOnError = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall)) + { + sqlScript.ExecuteOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall)) + { + sqlScript.ExecuteOnReinstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall)) + { + sqlScript.ExecuteOnUninstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall))) + { + sqlScript.RollbackOnInstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall))) + { + sqlScript.RollbackOnReinstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall))) + { + sqlScript.RollbackOnUninstall = Sql.YesNoType.yes; + } + + if (null != row[6]) + { + sqlScript.Sequence = (int)row[6]; + } + + this.Core.IndexElement(row, sqlScript); + } + } + + /// + /// Decompile the SqlString table. + /// + /// The table to decompile. + private void DecompileSqlStringTable(Table table) + { + foreach (Row row in table.Rows) + { + Sql.SqlString sqlString = new Sql.SqlString(); + + sqlString.Id = (string)row[0]; + + // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables + + sqlString.SQL = (string)row[3]; + + if (null != row[4]) + { + sqlString.User = (string)row[4]; + } + + int attributes = (int)row[5]; + + if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError)) + { + sqlString.ContinueOnError = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall)) + { + sqlString.ExecuteOnInstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall)) + { + sqlString.ExecuteOnReinstall = Sql.YesNoType.yes; + } + + if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall)) + { + sqlString.ExecuteOnUninstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall))) + { + sqlString.RollbackOnInstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall))) + { + sqlString.RollbackOnReinstall = Sql.YesNoType.yes; + } + + if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall))) + { + sqlString.RollbackOnUninstall = Sql.YesNoType.yes; + } + + if (null != row[6]) + { + sqlString.Sequence = (int)row[6]; + } + + this.Core.IndexElement(row, sqlString); + } + } + + /// + /// Finalize the SqlFileSpec table. + /// + /// The collection of all tables. + /// + /// Since rows of the SqlFileSpec table are represented by either + /// the SqlFileSpec or SqlLogFileSpec depending upon the context in + /// which they are used in the SqlDatabase table, decompilation of this + /// table must occur after the SqlDatbase parents are decompiled. + /// + private void FinalizeSqlFileSpecTable(TableIndexedCollection tables) + { + Table sqlDatabaseTable = tables["SqlDatabase"]; + Table sqlFileSpecTable = tables["SqlFileSpec"]; + + if (null != sqlDatabaseTable && null != sqlFileSpecTable) + { + Hashtable sqlFileSpecRows = new Hashtable(); + + // index each SqlFileSpec row by its primary key + foreach (Row row in sqlFileSpecTable.Rows) + { + sqlFileSpecRows.Add(row[0], row); + } + + // create the necessary SqlFileSpec and SqlLogFileSpec elements for each row + foreach (Row row in sqlDatabaseTable.Rows) + { + Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(row); + + if (null != row[6]) + { + Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[6]]; + + if (null != sqlFileSpecRow) + { + Sql.SqlFileSpec sqlFileSpec = new Sql.SqlFileSpec(); + + sqlFileSpec.Id = (string)sqlFileSpecRow[0]; + + if (null != sqlFileSpecRow[1]) + { + sqlFileSpec.Name = (string)sqlFileSpecRow[1]; + } + + sqlFileSpec.Filename = (string)sqlFileSpecRow[2]; + + if (null != sqlFileSpecRow[3]) + { + sqlFileSpec.Size = (string)sqlFileSpecRow[3]; + } + + if (null != sqlFileSpecRow[4]) + { + sqlFileSpec.MaxSize = (string)sqlFileSpecRow[4]; + } + + if (null != sqlFileSpecRow[5]) + { + sqlFileSpec.GrowthSize = (string)sqlFileSpecRow[5]; + } + + sqlDatabase.AddChild(sqlFileSpec); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_", (string)row[6], "SqlFileSpec")); + } + } + + if (null != row[7]) + { + Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[7]]; + + if (null != sqlFileSpecRow) + { + Sql.SqlLogFileSpec sqlLogFileSpec = new Sql.SqlLogFileSpec(); + + sqlLogFileSpec.Id = (string)sqlFileSpecRow[0]; + + if (null != sqlFileSpecRow[1]) + { + sqlLogFileSpec.Name = (string)sqlFileSpecRow[1]; + } + + sqlLogFileSpec.Filename = (string)sqlFileSpecRow[2]; + + if (null != sqlFileSpecRow[3]) + { + sqlLogFileSpec.Size = (string)sqlFileSpecRow[3]; + } + + if (null != sqlFileSpecRow[4]) + { + sqlLogFileSpec.MaxSize = (string)sqlFileSpecRow[4]; + } + + if (null != sqlFileSpecRow[5]) + { + sqlLogFileSpec.GrowthSize = (string)sqlFileSpecRow[5]; + } + + sqlDatabase.AddChild(sqlLogFileSpec); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_Log", (string)row[7], "SqlFileSpec")); + } + } + } + } + } + + /// + /// Finalize the SqlScript table. + /// + /// The collection of all tables. + /// + /// The SqlScript and SqlString tables contain a foreign key into the SqlDatabase + /// and Component tables. Depending upon the parent of the SqlDatabase + /// element, the SqlScript and SqlString elements are nested under either the + /// SqlDatabase or the Component element. + /// + private void FinalizeSqlScriptAndSqlStringTables(TableIndexedCollection tables) + { + Table sqlDatabaseTable = tables["SqlDatabase"]; + Table sqlScriptTable = tables["SqlScript"]; + Table sqlStringTable = tables["SqlString"]; + + Hashtable sqlDatabaseRows = new Hashtable(); + + // index each SqlDatabase row by its primary key + if (null != sqlDatabaseTable) + { + foreach (Row row in sqlDatabaseTable.Rows) + { + sqlDatabaseRows.Add(row[0], row); + } + } + + if (null != sqlScriptTable) + { + foreach (Row row in sqlScriptTable.Rows) + { + Sql.SqlScript sqlScript = (Sql.SqlScript)this.Core.GetIndexedElement(row); + + Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]]; + string databaseComponent = (string)sqlDatabaseRow[4]; + + // determine if the SqlScript element should be nested under the database or another component + if (null != databaseComponent && databaseComponent == (string)row[2]) + { + Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow); + + sqlDatabase.AddChild(sqlScript); + } + else // nest under the component of the SqlDatabase row + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); + + // set the Database value + sqlScript.SqlDb = (string)row[1]; + + if (null != component) + { + component.AddChild(sqlScript); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlScriptTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); + } + } + } + } + + if (null != sqlStringTable) + { + foreach (Row row in sqlStringTable.Rows) + { + Sql.SqlString sqlString = (Sql.SqlString)this.Core.GetIndexedElement(row); + + Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]]; + string databaseComponent = (string)sqlDatabaseRow[4]; + + // determine if the SqlScript element should be nested under the database or another component + if (null != databaseComponent && databaseComponent == (string)row[2]) + { + Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow); + + sqlDatabase.AddChild(sqlString); + } + else // nest under the component of the SqlDatabase row + { + Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]); + + // set the Database value + sqlString.SqlDb = (string)row[1]; + + if (null != component) + { + component.AddChild(sqlString); + } + else + { + this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlStringTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component")); + } + } + } + } + } + } +} diff --git a/src/wixext/SqlErrors.cs b/src/wixext/SqlErrors.cs new file mode 100644 index 00000000..2043b658 --- /dev/null +++ b/src/wixext/SqlErrors.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensions +{ + public sealed class SqlErrors + { + + private SqlErrors() + { + } + + public static MessageEventArgs IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName) + { + return new SqlErrorEventArgs(sourceLineNumbers, 5100, "SqlErrors_IllegalAttributeWithoutComponent_1", elementName, attributeName); + } + + public static MessageEventArgs IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName) + { + return new SqlErrorEventArgs(sourceLineNumbers, 5101, "SqlErrors_IllegalElementWithoutComponent_1", elementName); + } + + public static MessageEventArgs OneOfAttributesRequiredUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2, string attributeName3, string attributeName4) + { + return new SqlErrorEventArgs(sourceLineNumbers, 5102, "SqlErrors_OneOfAttributesRequiredUnderComponent_1", elementName, attributeName1, attributeName2, attributeName3, attributeName4); + } + + public static MessageEventArgs DeprecatedBinaryChildElement(SourceLineNumber sourceLineNumbers, string elementName) + { + return new SqlErrorEventArgs(sourceLineNumbers, 5103, "SqlErrors_DeprecatedBinaryChildElement_1", elementName); + } + } +} \ No newline at end of file diff --git a/src/wixext/SqlExtensionData.cs b/src/wixext/SqlExtensionData.cs new file mode 100644 index 00000000..b43b0341 --- /dev/null +++ b/src/wixext/SqlExtensionData.cs @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.Extensions +{ + using System; + using System.Reflection; + using WixToolset.Data; + using WixToolset.Extensibility; + + /// + /// The WiX Toolset SQL Server Extension. + /// + public sealed class SqlExtensionData : ExtensionData + { + /// + /// Gets the default culture. + /// + /// The default culture. + public override string DefaultCulture + { + get { return "en-us"; } + } + + /// + /// Gets the optional table definitions for this extension. + /// + /// The optional table definitions for this extension. + public override TableDefinitionCollection TableDefinitions + { + get + { + return SqlExtensionData.GetExtensionTableDefinitions(); + } + } + + /// + /// Gets the library associated with this extension. + /// + /// The table definitions to use while loading the library. + /// The loaded library. + public override Library GetLibrary(TableDefinitionCollection tableDefinitions) + { + return SqlExtensionData.GetExtensionLibrary(tableDefinitions); + } + + /// + /// Internal mechanism to access the extension's table definitions. + /// + /// Extension's table definitions. + internal static TableDefinitionCollection GetExtensionTableDefinitions() + { + return ExtensionData.LoadTableDefinitionHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.tables.xml"); + } + + /// + /// Internal mechanism to access the extension's library. + /// + /// Extension's library. + internal static Library GetExtensionLibrary(TableDefinitionCollection tableDefinitions) + { + return ExtensionData.LoadLibraryHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.sql.wixlib", tableDefinitions); + } + } +} diff --git a/src/wixext/sql.xsd b/src/wixext/sql.xsd new file mode 100644 index 00000000..161607c9 --- /dev/null +++ b/src/wixext/sql.xsd @@ -0,0 +1,342 @@ + + + + + + + + The source code schema for the WiX Toolset SQL Server Extension. + + + + + + + + + + + + + + + Nesting SqlDatabase under a Component element will result in a SqlDatabase being installed to the machine as the package is installed. + + Nesting SqlDatabase under Product, Fragment, or Module + results in a database "locator" record being created in + the SqlDatabase table. This means that the database + itself is neither installed nor uninstalled by the MSI + package. It does make the database available for referencing + from a SqlString or SqlScript record. This allows MSI to install + SqlScripts or SqlStrings to already existing databases on the machine. + The install will fail if the database does not exist in these cases. + + + The User attribute references credentials specified in a User element. + If a user is not specified then Windows Authentication will be used by default + using the credentials of the user performing the install to execute sql + strings, etc. + + + + + + SQL Database + + + + + + + + + + + + + + + + + + + The name of the database. The value can be a literal value or derived from a + Property element using the Formatted + syntax. + + + + + + + + + + + Specifies whether to create the database when the associated component is reinstalled. Setting CreateOnInstall to yes does not imply CreateOnReinstall is set to yes. CreateOnReinstall must be set in addition to CreateOnInstall for it to be created during both install and reinstall. + + + + + + + + + + + Specifies whether to drop the database when the associated component is reinstalled. Setting DropOnInstall to yes does not imply DropOnReinstall is set to yes. DropOnReinstall must be set in addition to DropOnInstall for it to be dropped during both install and reinstall. + + + + + + + + + + + + + + + File specification for a Sql database. + + + + + ID of the file specification. + + + + + Specifies the logical name for the database file. + + + + + Specifies the operating-system file name for the database file. + + + + + + Specifies the size of the database file. The GB, MB and KB suffixes can be used to specify gigabytes, + megabytes or kilobytes. The default is megabytes if no suffix is specified. When a Size is not + supplied for a database file, SQL Server uses the size of the primary file in the model database. + + + + + + + Specifies the maximum size to which the database file can grow. The GB, MB and KB suffixes can be used to + to specify gigabytes, megabytes or kilobytes. The default is megabytes if no suffix is specified. If + MaxSize is not specified, the file will grow until the disk is full. + + + + + + + Specifies the growth increment of the database file. The GB, MB and KB and % suffixes can be used to + specify gigabytes, megabytes, kilobytes or a percentage of the current file size to grow. The default is + megabytes if no suffix is specified. The default value is 10% if GrowthSize is not specified, and the + minimum value is 64 KB. The GrowthSize setting for a file cannot exceed the MaxSize setting. + + + + + + + + + File specification for a Sql database. + + + + + ID of the log file specification. + + + + + Specifies the logical name for the log file. + + + + + Specifies the operating-system file name for the log file. + + + + + + Specifies the size of the log file. The GB, MB and KB suffixes can be used to specify gigabytes, + megabytes or kilobytes. The default is megabytes if no suffix is specified. When a Size is not + supplied for a log file, SQL Server makes the file 1 MB. + + + + + + + Specifies the maximum size to which the log file can grow. The GB, MB and KB suffixes can be used to + to specify gigabytes, megabytes or kilobytes. The default is megabytes if no suffix is specified. If + MaxSize is not specified, the file will grow until the disk is full. + + + + + + + Specifies the growth increment of the log file. The GB, MB and KB and % suffixes can be used to + specify gigabytes, megabytes, kilobytes or a percentage of the current file size to grow. The default is + megabytes if no suffix is specified. The default value is 10% if GrowthSize is not specified, and the + minimum value is 64 KB. The GrowthSize setting for a file cannot exceed the MaxSize setting. + + + + + + + + + + + + SQL Script + + + + + + required when not child of SqlDatabase + + + + + + + Reference to Binary stream that contains the SQL script to execute. + + + + + Specifies to execute the script when the associated component is installed. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes. + + + + + Specifies whether to execute the script when the associated component is reinstalled. Setting ExecuteOnInstall to yes does not imply ExecuteOnReinstall is set to yes. ExecuteOnReinstall must be set in addition to ExecuteOnInstall for it to be executed during both install and reinstall. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes. + + + + + Specifies to execute the script when the associated component is uninstalled. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes. + + + + + Specifies whether to execute the script on rollback if an attempt is made to install the associated component. This attribute is mutually exclusive with the ExecuteOnInstall, ExecuteOnReinstall and ExecuteOnUninstall attributes. + + + + + Specifies whether to execute the script on rollback if an attempt is made to reinstall the associated component. This attribute is mutually exclusive with the ExecuteOnInstall, ExecuteOnReinstall and ExecuteOnUninstall attributes. + + + + + Specifies whether to execute the script on rollback if an attempt is made to uninstall the associated component. This attribute is mutually exclusive with the ExecuteOnInstall, ExecuteOnReinstall and ExecuteOnUninstall attributes. + + + + + Continue executing scripts even if this one fails. + + + + + Specifes the order to run the SQL Scripts. It is recommended that rollback scripts be scheduled before their complementary execution script. This order is also relative across the SqlString element. + + + + + + + + + + + SQL String + + + + + + + + + + + + + Specifies to execute the string when the associated component is installed. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes. + + + + + + Specifies whether to execute the string when the associated component is reinstalled. Setting ExecuteOnInstall to yes does not imply ExecuteOnReinstall is set to yes. ExecuteOnReinstall must be set in addition to ExecuteOnInstall for it to be executed during both install and reinstall. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes. + + + + + + Specifies to execute the string when the associated component is uninstalled. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes. + + + + + Specifies whether to execute the string on rollback if an attempt is made to install the associated component. This attribute is mutually exclusive with the ExecuteOnInstall, ExecuteOnReinstall and ExecuteOnUninstall attributes. + + + + + Specifies whether to execute the string on rollback if an attempt is made to reinstall the associated component. This attribute is mutually exclusive with the ExecuteOnInstall, ExecuteOnReinstall and ExecuteOnUninstall attributes. + + + + + Specifies whether to execute the string on rollback if an attempt is made to uninstall the associated component. This attribute is mutually exclusive with the ExecuteOnInstall, ExecuteOnReinstall and ExecuteOnUninstall attributes. + + + + + Continue executing strings even if this one fails. + + + + + Specifes the order to run the SQL Strings. It is recommended that rollback strings be scheduled before their complementary execution string. This order is also relative across the SqlScript element. + + + + + + + + Values of this type will either be "yes" or "no". + + + + + + + + diff --git a/src/wixext/tables.xml b/src/wixext/tables.xml new file mode 100644 index 00000000..a8b6c3a1 --- /dev/null +++ b/src/wixext/tables.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/wixlib/SqlExtension.wxs b/src/wixlib/SqlExtension.wxs new file mode 100644 index 00000000..2ee9a3ab --- /dev/null +++ b/src/wixlib/SqlExtension.wxs @@ -0,0 +1,46 @@ + + + + + + + + + + + + !(loc.msierrSQLFailedCreateDatabase) + !(loc.msierrSQLFailedDropDatabase) + !(loc.msierrSQLFailedConnectDatabase) + !(loc.msierrSQLFailedExecString) + !(loc.msierrSQLDatabaseAlreadyExists) + + !(loc.ConfigureSql) + !(loc.ConfigureSql) + !(loc.CreateDatabase) + !(loc.DropDatabase) + !(loc.ExecuteSqlStrings) + !(loc.RollbackExecuteSqlStrings) + + + + + + + + + + + + + NOT SKIPUNINSTALLSQLDATA AND VersionNT > 400 + NOT SKIPINSTALLSQLDATA AND VersionNT > 400 + + + + + + + + + diff --git a/src/wixlib/de-de.wxl b/src/wixlib/de-de.wxl new file mode 100644 index 00000000..39a73e8c --- /dev/null +++ b/src/wixlib/de-de.wxl @@ -0,0 +1,17 @@ + + + + + + Fehler [2]: Erstellen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4]. + Fehler [2]: Löschen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4]. + Verbinden mit der SQL-Datenbank fehlgeschlagen. ([2] [3] [4] [5]) + Fehler [2]: Das Erstellen der SQL Zeichenfolge ist fehlgeschlagen, Fehlerbeschreibung: [3], SQL-Schlüssel: [4] SQL-Zeichenfolge: [5] + Die Datenbank [3] existiert bereits. Wollen Sie fortfahren? + + Konfiguriere SQL Server + Erstelle Datenbanken + Lösche Datenbanken + SQL-Zeichenfolgen werden erstellt + SQL-Zeichenfolgen werden zurückgesetzt + diff --git a/src/wixlib/en-us.wxl b/src/wixlib/en-us.wxl new file mode 100644 index 00000000..d89b1c6c --- /dev/null +++ b/src/wixlib/en-us.wxl @@ -0,0 +1,17 @@ + + + + + + Error [2]: failed to create SQL database: [3], error detail: [4]. + Error [2]: failed to drop SQL database: [3], error detail: [4]. + Failed to connect to SQL database. ([2] [3] [4] [5]) + Error [2]: failed to execute SQL string, error detail: [3], SQL key: [4] SQL string: [5] + The database [3] already exists. Do you want to continue? + + Configuring SQL Server + Creating Databases + Dropping Databases + Executing SQL Strings + Rolling back SQL Strings + diff --git a/src/wixlib/es-es.wxl b/src/wixlib/es-es.wxl new file mode 100644 index 00000000..bc5d0582 --- /dev/null +++ b/src/wixlib/es-es.wxl @@ -0,0 +1,18 @@ + + + + + + Error [2]: falla al crear la base de datos SQL: [3], detalle del error: [4]. + Error [2]: falla al poner la base de datos SQL: [3], detalle del error: [4]. + Falla al conectarse con la base de datos SQL. ([2] [3] [4] [5]) + Error [2]: falla al ejecutar la cadena SQL, detalle del error: [3], Clave SQL: [4] Cadena SQL: [5] + La base de datos [3] ya existe. ¿Desea continuar? + + Configurando SQL Server + Creando Bases de Datos + Colocando Bases de Datos + Ejecutando cadenas SQL + Revirtiendo cadenas SQL + + diff --git a/src/wixlib/ja-jp.wxl b/src/wixlib/ja-jp.wxl new file mode 100644 index 00000000..23c9aebe --- /dev/null +++ b/src/wixlib/ja-jp.wxl @@ -0,0 +1,17 @@ + + + + + + エラー [2]: SQL データベース [3] 作成に失敗しました、エラー詳細: [4]。 + エラー [2]: SQL データベース [3] の削除に失敗しました、エラー詳細: [4]。 + SQL データベースへ接続できませんでした。 ([2] [3] [4] [5]) + エラー [2]: SQL ストリングの実行に失敗しました、エラー詳細: [3]、 SQL キー: [4] SQL ストリング: [5] + データベース [3] は既に存在します。続行しますか? + + SQL サーバーを構成しています + データベースを作成しています + データベースを削除しています + SQL ストリングを実行しています + SQL ストリングをロールバックしています + diff --git a/src/wixlib/pl-pl.wxl b/src/wixlib/pl-pl.wxl new file mode 100644 index 00000000..4f0c7f75 --- /dev/null +++ b/src/wixlib/pl-pl.wxl @@ -0,0 +1,17 @@ + + + + + + Błąd [2]: nie udało się utworzyć bazy danych: [3]. Szczegóły błędu: [4]. + Błąd [2]: nie udało się usunąć bazy danych: [3]. Szczegóły błędu: [4]. + Nie udało się połączyć z bazą danych. ([2] [3] [4] [5]) + Błąd [2]: nie udało się wykonać zapytania SQL. Szczegóły błędu: [3], klucz: [4] zapytanie SQL: [5] + Baza danych [3] już istnieje. Czy chcesz kontynuować? + + Konfigurowanie programu SQL Server + Tworzenie baz danych + Usuwanie baz danych + Wykonywanie zapytań SQL + Cofanie zapytań SQL + diff --git a/src/wixlib/pt-br.wxl b/src/wixlib/pt-br.wxl new file mode 100644 index 00000000..63bbc21e --- /dev/null +++ b/src/wixlib/pt-br.wxl @@ -0,0 +1,17 @@ + + + + + + Error [2]: falha ao criar o Banco de Dados: [3], detalhes: [4]. + Error [2]: falha ao remover o Banco de Dados: [3], detalhes: [4]. + Falhou a ligação ao Banco de Dados. ([2] [3] [4] [5]) + Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5] + O Banco de Dados [3] já existe. Deseja continuar? + + Configurando o Servidor de SQL + Criando os Bancos de Dados + Removendo os Bancos de Dados + Executando comandos de SQL + Revertendo os comandos de SQL + diff --git a/src/wixlib/pt-pt.wxl b/src/wixlib/pt-pt.wxl new file mode 100644 index 00000000..28c43878 --- /dev/null +++ b/src/wixlib/pt-pt.wxl @@ -0,0 +1,17 @@ + + + + + + Error [2]: falha ao criar a Base de Dados: [3], detalhes: [4]. + Error [2]: falha ao remover a Base de Dados: [3], detalhes: [4]. + Falhou a ligação à Base de Dados. ([2] [3] [4] [5]) + Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5] + A Base de Dados [3] já existe. Deseja continuar? + + Configurar o Servidor de SQL + Criar as Bases de Dados + Remover as Bases de Dados + Executar comandos de SQL + Reverter os comandos de SQL + -- cgit v1.2.3-55-g6feb