aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2018-12-15 22:40:06 -0600
committerSean Hall <r.sean.hall@gmail.com>2018-12-15 22:40:06 -0600
commit8464662dfcf3a6e4fafc33440b33236773d96a65 (patch)
tree33c26606c2a1df6f4c0b8a5665b34899fc57edc8
parentc3442d8c8e2cbc71b077e1625a854aa2e871a544 (diff)
downloadwix-8464662dfcf3a6e4fafc33440b33236773d96a65.tar.gz
wix-8464662dfcf3a6e4fafc33440b33236773d96a65.tar.bz2
wix-8464662dfcf3a6e4fafc33440b33236773d96a65.zip
Import code from old v4 repo
-rw-r--r--src/wixext/SqlCompiler.cs793
-rw-r--r--src/wixext/SqlDecompiler.cs512
-rw-r--r--src/wixext/SqlErrors.cs32
-rw-r--r--src/wixext/SqlExtensionData.cs64
-rw-r--r--src/wixext/sql.xsd342
-rw-r--r--src/wixext/tables.xml73
-rw-r--r--src/wixlib/SqlExtension.wxs46
-rw-r--r--src/wixlib/de-de.wxl17
-rw-r--r--src/wixlib/en-us.wxl17
-rw-r--r--src/wixlib/es-es.wxl18
-rw-r--r--src/wixlib/ja-jp.wxl17
-rw-r--r--src/wixlib/pl-pl.wxl17
-rw-r--r--src/wixlib/pt-br.wxl17
-rw-r--r--src/wixlib/pt-pt.wxl17
14 files changed, 1982 insertions, 0 deletions
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 @@
1// 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.
2
3namespace WixToolset.Extensions
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Xml.Linq;
8 using WixToolset.Data;
9 using WixToolset.Extensibility;
10
11 /// <summary>
12 /// The compiler for the WiX Toolset SQL Server Extension.
13 /// </summary>
14 public sealed class SqlCompiler : CompilerExtension
15 {
16 // sql database attributes definitions (from sca.h)
17 internal const int DbCreateOnInstall = 0x00000001;
18 internal const int DbDropOnUninstall = 0x00000002;
19 internal const int DbContinueOnError = 0x00000004;
20 internal const int DbDropOnInstall = 0x00000008;
21 internal const int DbCreateOnUninstall = 0x00000010;
22 internal const int DbConfirmOverwrite = 0x00000020;
23 internal const int DbCreateOnReinstall = 0x00000040;
24 internal const int DbDropOnReinstall = 0x00000080;
25
26 // sql string/script attributes definitions (from sca.h)
27 internal const int SqlExecuteOnInstall = 0x00000001;
28 internal const int SqlExecuteOnUninstall = 0x00000002;
29 internal const int SqlContinueOnError = 0x00000004;
30 internal const int SqlRollback = 0x00000008;
31 internal const int SqlExecuteOnReinstall = 0x00000010;
32
33 /// <summary>
34 /// Instantiate a new SqlCompiler.
35 /// </summary>
36 public SqlCompiler()
37 {
38 this.Namespace = "http://wixtoolset.org/schemas/v4/wxs/sql";
39 }
40
41 /// <summary>
42 /// Processes an element for the Compiler.
43 /// </summary>
44 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
45 /// <param name="parentElement">Parent element of element to process.</param>
46 /// <param name="element">Element to process.</param>
47 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
48 public override void ParseElement(XElement parentElement, XElement element, IDictionary<string, string> context)
49 {
50 switch (parentElement.Name.LocalName)
51 {
52 case "Component":
53 string componentId = context["ComponentId"];
54 string directoryId = context["DirectoryId"];
55
56 switch (element.Name.LocalName)
57 {
58 case "SqlDatabase":
59 this.ParseSqlDatabaseElement(element, componentId);
60 break;
61 case "SqlScript":
62 this.ParseSqlScriptElement(element, componentId, null);
63 break;
64 case "SqlString":
65 this.ParseSqlStringElement(element, componentId, null);
66 break;
67 default:
68 this.Core.UnexpectedElement(parentElement, element);
69 break;
70 }
71 break;
72 case "Fragment":
73 case "Module":
74 case "Product":
75 switch (element.Name.LocalName)
76 {
77 case "SqlDatabase":
78 this.ParseSqlDatabaseElement(element, null);
79 break;
80 default:
81 this.Core.UnexpectedElement(parentElement, element);
82 break;
83 }
84 break;
85 default:
86 this.Core.UnexpectedElement(parentElement, element);
87 break;
88 }
89 }
90
91 /// <summary>
92 /// Parses a sql database element
93 /// </summary>
94 /// <param name="node">Element to parse.</param>
95 /// <param name="componentId">Identifier for parent component.</param>
96 private void ParseSqlDatabaseElement(XElement node, string componentId)
97 {
98 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
99 string id = null;
100 int attributes = 0;
101 string database = null;
102 string fileSpec = null;
103 string instance = null;
104 string logFileSpec = null;
105 string server = null;
106 string user = null;
107
108 foreach (XAttribute attrib in node.Attributes())
109 {
110 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
111 {
112 switch (attrib.Name.LocalName)
113 {
114 case "Id":
115 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
116 break;
117 case "ConfirmOverwrite":
118 if (null == componentId)
119 {
120 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
121 }
122
123 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
124 {
125 attributes |= DbConfirmOverwrite;
126 }
127 break;
128 case "ContinueOnError":
129 if (null == componentId)
130 {
131 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
132 }
133
134 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
135 {
136 attributes |= DbContinueOnError;
137 }
138 break;
139 case "CreateOnInstall":
140 if (null == componentId)
141 {
142 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
143 }
144
145 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
146 {
147 attributes |= DbCreateOnInstall;
148 }
149 break;
150 case "CreateOnReinstall":
151 if (null == componentId)
152 {
153 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
154 }
155
156 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
157 {
158 attributes |= DbCreateOnReinstall;
159 }
160 break;
161 case "CreateOnUninstall":
162 if (null == componentId)
163 {
164 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
165 }
166
167 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
168 {
169 attributes |= DbCreateOnUninstall;
170 }
171 break;
172 case "Database":
173 database = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
174 break;
175 case "DropOnInstall":
176 if (null == componentId)
177 {
178 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
179 }
180
181 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
182 {
183 attributes |= DbDropOnInstall;
184 }
185 break;
186 case "DropOnReinstall":
187 if (null == componentId)
188 {
189 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
190 }
191
192 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
193 {
194 attributes |= DbDropOnReinstall;
195 }
196 break;
197
198 case "DropOnUninstall":
199 if (null == componentId)
200 {
201 this.Core.OnMessage(SqlErrors.IllegalAttributeWithoutComponent(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName));
202 }
203
204 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
205 {
206 attributes |= DbDropOnUninstall;
207 }
208 break;
209 case "Instance":
210 instance = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
211 break;
212 case "Server":
213 server = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
214 break;
215 case "User":
216 user = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
217 if (!this.Core.ContainsProperty(user))
218 {
219 user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
220 this.Core.CreateSimpleReference(sourceLineNumbers, "User", user);
221 }
222 break;
223 default:
224 this.Core.UnexpectedAttribute(node, attrib);
225 break;
226 }
227 }
228 else
229 {
230 this.Core.ParseExtensionAttribute(node, attrib);
231 }
232 }
233
234 if (null == id)
235 {
236 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
237 }
238
239 if (null == database)
240 {
241 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Database"));
242 }
243 else if (128 < database.Length)
244 {
245 this.Core.OnMessage(WixErrors.IdentifierTooLongError(sourceLineNumbers, node.Name.LocalName, "Database", database, 128));
246 }
247
248 if (null == server)
249 {
250 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Server"));
251 }
252
253 if (0 == attributes && null != componentId)
254 {
255 this.Core.OnMessage(SqlErrors.OneOfAttributesRequiredUnderComponent(sourceLineNumbers, node.Name.LocalName, "CreateOnInstall", "CreateOnUninstall", "DropOnInstall", "DropOnUninstall"));
256 }
257
258 foreach (XElement child in node.Elements())
259 {
260 if (this.Namespace == child.Name.Namespace)
261 {
262 SourceLineNumber childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
263 switch (child.Name.LocalName)
264 {
265 case "SqlScript":
266 if (null == componentId)
267 {
268 this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName));
269 }
270
271 this.ParseSqlScriptElement(child, componentId, id);
272 break;
273 case "SqlString":
274 if (null == componentId)
275 {
276 this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName));
277 }
278
279 this.ParseSqlStringElement(child, componentId, id);
280 break;
281 case "SqlFileSpec":
282 if (null == componentId)
283 {
284 this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName));
285 }
286 else if (null != fileSpec)
287 {
288 this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, 1));
289 }
290
291 fileSpec = this.ParseSqlFileSpecElement(child);
292 break;
293 case "SqlLogFileSpec":
294 if (null == componentId)
295 {
296 this.Core.OnMessage(SqlErrors.IllegalElementWithoutComponent(childSourceLineNumbers, child.Name.LocalName));
297 }
298 else if (null != logFileSpec)
299 {
300 this.Core.OnMessage(WixErrors.TooManyElements(sourceLineNumbers, node.Name.LocalName, child.Name.LocalName, 1));
301 }
302
303 logFileSpec = this.ParseSqlFileSpecElement(child);
304 break;
305 default:
306 this.Core.UnexpectedElement(node, child);
307 break;
308 }
309 }
310 else
311 {
312 this.Core.ParseExtensionElement(node, child);
313 }
314 }
315
316 if (null != componentId)
317 {
318 // Reference InstallSqlData and UninstallSqlData since nothing will happen without it
319 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallSqlData");
320 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "UninstallSqlData");
321 }
322
323 if (!this.Core.EncounteredError)
324 {
325 Row row = this.Core.CreateRow(sourceLineNumbers, "SqlDatabase");
326 row[0] = id;
327 row[1] = server;
328 row[2] = instance;
329 row[3] = database;
330 row[4] = componentId;
331 row[5] = user;
332 row[6] = fileSpec;
333 row[7] = logFileSpec;
334 if (0 != attributes)
335 {
336 row[8] = attributes;
337 }
338 }
339 }
340
341 /// <summary>
342 /// Parses a sql file specification element.
343 /// </summary>
344 /// <param name="node">Element to parse.</param>
345 /// <returns>Identifier of sql file specification.</returns>
346 private string ParseSqlFileSpecElement(XElement node)
347 {
348 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
349 string id = null;
350 string fileName = null;
351 string growthSize = null;
352 string maxSize = null;
353 string name = null;
354 string size = null;
355
356 foreach (XAttribute attrib in node.Attributes())
357 {
358 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
359 {
360 switch (attrib.Name.LocalName)
361 {
362 case "Id":
363 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
364 break;
365 case "Name":
366 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
367 break;
368 case "Filename":
369 fileName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
370 break;
371 case "Size":
372 size = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
373 break;
374 case "MaxSize":
375 maxSize = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
376 break;
377 case "GrowthSize":
378 growthSize = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
379 break;
380 default:
381 this.Core.UnexpectedAttribute(node, attrib);
382 break;
383 }
384 }
385 else
386 {
387 this.Core.ParseExtensionAttribute(node, attrib);
388 }
389 }
390
391 if (null == id)
392 {
393 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
394 }
395
396 if (null == name)
397 {
398 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
399 }
400
401 if (null == fileName)
402 {
403 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Filename"));
404 }
405
406 this.Core.ParseForExtensionElements(node);
407
408 if (!this.Core.EncounteredError)
409 {
410 Row row = this.Core.CreateRow(sourceLineNumbers, "SqlFileSpec");
411 row[0] = id;
412 row[1] = name;
413 row[2] = fileName;
414 if (null != size)
415 {
416 row[3] = size;
417 }
418
419 if (null != maxSize)
420 {
421 row[4] = maxSize;
422 }
423
424 if (null != growthSize)
425 {
426 row[5] = growthSize;
427 }
428 }
429
430 return id;
431 }
432
433 /// <summary>
434 /// Parses a sql script element.
435 /// </summary>
436 /// <param name="node">Element to parse.</param>
437 /// <param name="componentId">Identifier for parent component.</param>
438 /// <param name="sqlDb">Optional database to execute script against.</param>
439 private void ParseSqlScriptElement(XElement node, string componentId, string sqlDb)
440 {
441 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
442 string id = null;
443 int attributes = 0;
444 bool rollbackAttribute = false;
445 bool nonRollbackAttribute = false;
446 string binary = null;
447 int sequence = CompilerConstants.IntegerNotSet;
448 string user = null;
449
450 foreach (XAttribute attrib in node.Attributes())
451 {
452 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
453 {
454 switch (attrib.Name.LocalName)
455 {
456 case "Id":
457 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
458 break;
459 case "BinaryKey":
460 binary = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
461 this.Core.CreateSimpleReference(sourceLineNumbers, "Binary", binary);
462 break;
463 case "Sequence":
464 sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
465 break;
466 case "SqlDb":
467 if (null != sqlDb)
468 {
469 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, node.Parent.Name.LocalName));
470 }
471 sqlDb = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
472 this.Core.CreateSimpleReference(sourceLineNumbers, "SqlDatabase", sqlDb);
473 break;
474 case "User":
475 user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
476 this.Core.CreateSimpleReference(sourceLineNumbers, "User", user);
477 break;
478
479 // Flag-setting attributes
480 case "ContinueOnError":
481 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
482 {
483 attributes |= SqlContinueOnError;
484 }
485 break;
486 case "ExecuteOnInstall":
487 if (rollbackAttribute)
488 {
489 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
490 }
491 nonRollbackAttribute = true;
492
493 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
494 {
495 attributes |= SqlExecuteOnInstall;
496 }
497 break;
498 case "ExecuteOnReinstall":
499 if (rollbackAttribute)
500 {
501 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
502 }
503 nonRollbackAttribute = true;
504
505 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
506 {
507 attributes |= SqlExecuteOnReinstall;
508 }
509 break;
510 case "ExecuteOnUninstall":
511 if (rollbackAttribute)
512 {
513 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
514 }
515 nonRollbackAttribute = true;
516
517 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
518 {
519 attributes |= SqlExecuteOnUninstall;
520 }
521 break;
522 case "RollbackOnInstall":
523 if (nonRollbackAttribute)
524 {
525 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall"));
526 }
527 rollbackAttribute = true;
528
529 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
530 {
531 attributes |= SqlExecuteOnInstall;
532 attributes |= SqlRollback;
533 }
534 break;
535 case "RollbackOnReinstall":
536 if (nonRollbackAttribute)
537 {
538 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall"));
539 }
540 rollbackAttribute = true;
541
542 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
543 {
544 attributes |= SqlExecuteOnReinstall;
545 attributes |= SqlRollback;
546 }
547 break;
548 case "RollbackOnUninstall":
549 if (nonRollbackAttribute)
550 {
551 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall"));
552 }
553 rollbackAttribute = true;
554
555 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
556 {
557 attributes |= SqlExecuteOnUninstall;
558 attributes |= SqlRollback;
559 }
560 break;
561 default:
562 this.Core.UnexpectedAttribute(node, attrib);
563 break;
564 }
565 }
566 else
567 {
568 this.Core.ParseExtensionAttribute(node, attrib);
569 }
570 }
571
572 if (null == id)
573 {
574 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
575 }
576
577 if (null == binary)
578 {
579 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "BinaryKey"));
580 }
581
582 if (null == sqlDb)
583 {
584 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SqlDb"));
585 }
586
587 if (0 == attributes)
588 {
589 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
590 }
591
592 this.Core.ParseForExtensionElements(node);
593
594 // Reference InstallSqlData and UninstallSqlData since nothing will happen without it
595 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallSqlData");
596 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "UninstallSqlData");
597
598 if (!this.Core.EncounteredError)
599 {
600 Row row = this.Core.CreateRow(sourceLineNumbers, "SqlScript");
601 row[0] = id;
602 row[1] = sqlDb;
603 row[2] = componentId;
604 row[3] = binary;
605 row[4] = user;
606 row[5] = attributes;
607 if (CompilerConstants.IntegerNotSet != sequence)
608 {
609 row[6] = sequence;
610 }
611 }
612 }
613
614 /// <summary>
615 /// Parses a sql string element.
616 /// </summary>
617 /// <param name="node">Element to parse.</param>
618 /// <param name="componentId">Identifier for parent component.</param>
619 /// <param name="sqlDb">Optional database to execute string against.</param>
620 private void ParseSqlStringElement(XElement node, string componentId, string sqlDb)
621 {
622 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
623 string id = null;
624 int attributes = 0;
625 bool rollbackAttribute = false;
626 bool nonRollbackAttribute = false;
627 int sequence = CompilerConstants.IntegerNotSet;
628 string sql = null;
629 string user = null;
630
631 foreach (XAttribute attrib in node.Attributes())
632 {
633 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
634 {
635 switch (attrib.Name.LocalName)
636 {
637 case "Id":
638 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
639 break;
640 case "ContinueOnError":
641 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
642 {
643 attributes |= SqlContinueOnError;
644 }
645 break;
646 case "ExecuteOnInstall":
647 if (rollbackAttribute)
648 {
649 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
650 }
651 nonRollbackAttribute = true;
652
653 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
654 {
655 attributes |= SqlExecuteOnInstall;
656 }
657 break;
658 case "ExecuteOnReinstall":
659 if (rollbackAttribute)
660 {
661 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
662 }
663 nonRollbackAttribute = true;
664
665 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
666 {
667 attributes |= SqlExecuteOnReinstall;
668 }
669 break;
670 case "ExecuteOnUninstall":
671 if (rollbackAttribute)
672 {
673 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
674 }
675 nonRollbackAttribute = true;
676
677 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
678 {
679 attributes |= SqlExecuteOnUninstall;
680 }
681 break;
682 case "RollbackOnInstall":
683 if (nonRollbackAttribute)
684 {
685 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall"));
686 }
687 rollbackAttribute = true;
688
689 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
690 {
691 attributes |= SqlExecuteOnInstall;
692 attributes |= SqlRollback;
693 }
694 break;
695 case "RollbackOnReinstall":
696 if (nonRollbackAttribute)
697 {
698 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall"));
699 }
700 rollbackAttribute = true;
701
702 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
703 {
704 attributes |= SqlExecuteOnReinstall;
705 attributes |= SqlRollback;
706 }
707 break;
708 case "RollbackOnUninstall":
709 if (nonRollbackAttribute)
710 {
711 this.Core.OnMessage(WixErrors.IllegalAttributeWithOtherAttributes(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall"));
712 }
713 rollbackAttribute = true;
714
715 if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib))
716 {
717 attributes |= SqlExecuteOnUninstall;
718 attributes |= SqlRollback;
719 }
720 break;
721 case "Sequence":
722 sequence = this.Core.GetAttributeIntegerValue(sourceLineNumbers, attrib, 1, short.MaxValue);
723 break;
724 case "SQL":
725 sql = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
726 break;
727 case "SqlDb":
728 if (null != sqlDb)
729 {
730 this.Core.OnMessage(WixErrors.IllegalAttributeWhenNested(sourceLineNumbers, node.Name.LocalName, "SqlDb", "SqlDatabase"));
731 }
732
733 sqlDb = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
734 this.Core.CreateSimpleReference(sourceLineNumbers, "SqlDatabase", sqlDb);
735 break;
736 case "User":
737 user = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
738 this.Core.CreateSimpleReference(sourceLineNumbers, "User", user);
739 break;
740 default:
741 this.Core.UnexpectedAttribute(node, attrib);
742 break;
743 }
744 }
745 else
746 {
747 this.Core.ParseExtensionAttribute(node, attrib);
748 }
749 }
750
751 if (null == id)
752 {
753 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
754 }
755
756 if (null == sql)
757 {
758 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SQL"));
759 }
760
761 if (null == sqlDb)
762 {
763 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "SqlDb"));
764 }
765
766 if (0 == attributes)
767 {
768 this.Core.OnMessage(WixErrors.ExpectedAttributes(sourceLineNumbers, node.Name.LocalName, "ExecuteOnInstall", "ExecuteOnReinstall", "ExecuteOnUninstall", "RollbackOnInstall", "RollbackOnReinstall", "RollbackOnUninstall"));
769 }
770
771 this.Core.ParseForExtensionElements(node);
772
773 // Reference InstallSqlData and UninstallSqlData since nothing will happen without it
774 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "InstallSqlData");
775 this.Core.CreateSimpleReference(sourceLineNumbers, "CustomAction", "UninstallSqlData");
776
777 if (!this.Core.EncounteredError)
778 {
779 Row row = this.Core.CreateRow(sourceLineNumbers, "SqlString");
780 row[0] = id;
781 row[1] = sqlDb;
782 row[2] = componentId;
783 row[3] = sql;
784 row[4] = user;
785 row[5] = attributes;
786 if (CompilerConstants.IntegerNotSet != sequence)
787 {
788 row[6] = sequence;
789 }
790 }
791 }
792 }
793}
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 @@
1// 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.
2
3namespace WixToolset.Extensions
4{
5 using System.Collections;
6 using WixToolset.Data;
7 using WixToolset.Extensibility;
8 using Sql = WixToolset.Extensions.Serialize.Sql;
9 using Wix = WixToolset.Data.Serialize;
10
11 /// <summary>
12 /// The decompiler for the WiX Toolset SQL Server Extension.
13 /// </summary>
14 public sealed class SqlDecompiler : DecompilerExtension
15 {
16 /// <summary>
17 /// Creates a decompiler for SQL Extension.
18 /// </summary>
19 public SqlDecompiler()
20 {
21 this.TableDefinitions = SqlExtensionData.GetExtensionTableDefinitions();
22 }
23
24 /// <summary>
25 /// Get the extensions library to be removed.
26 /// </summary>
27 /// <param name="tableDefinitions">Table definitions for library.</param>
28 /// <returns>Library to remove from decompiled output.</returns>
29 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
30 {
31 return SqlExtensionData.GetExtensionLibrary(tableDefinitions);
32 }
33
34 /// <summary>
35 /// Decompiles an extension table.
36 /// </summary>
37 /// <param name="table">The table to decompile.</param>
38 public override void DecompileTable(Table table)
39 {
40 switch (table.Name)
41 {
42 case "SqlDatabase":
43 this.DecompileSqlDatabaseTable(table);
44 break;
45 case "SqlFileSpec":
46 // handled in FinalizeSqlFileSpecTable
47 break;
48 case "SqlScript":
49 this.DecompileSqlScriptTable(table);
50 break;
51 case "SqlString":
52 this.DecompileSqlStringTable(table);
53 break;
54 default:
55 base.DecompileTable(table);
56 break;
57 }
58 }
59
60 /// <summary>
61 /// Finalize decompilation.
62 /// </summary>
63 /// <param name="tables">The collection of all tables.</param>
64 public override void Finish(TableIndexedCollection tables)
65 {
66 this.FinalizeSqlFileSpecTable(tables);
67 this.FinalizeSqlScriptAndSqlStringTables(tables);
68 }
69
70 /// <summary>
71 /// Decompile the SqlDatabase table.
72 /// </summary>
73 /// <param name="table">The table to decompile.</param>
74 private void DecompileSqlDatabaseTable(Table table)
75 {
76 foreach (Row row in table.Rows)
77 {
78 Sql.SqlDatabase sqlDatabase = new Sql.SqlDatabase();
79
80 sqlDatabase.Id = (string)row[0];
81
82 if (null != row[1])
83 {
84 sqlDatabase.Server = (string)row[1];
85 }
86
87 if (null != row[2])
88 {
89 sqlDatabase.Instance = (string)row[2];
90 }
91
92 sqlDatabase.Database = (string)row[3];
93
94 if (null != row[5])
95 {
96 sqlDatabase.User = (string)row[5];
97 }
98
99 // the FileSpec_ and FileSpec_Log columns will be handled in FinalizeSqlFileSpecTable
100
101 if (null != row[8])
102 {
103 int attributes = (int)row[8];
104
105 if (SqlCompiler.DbCreateOnInstall == (attributes & SqlCompiler.DbCreateOnInstall))
106 {
107 sqlDatabase.CreateOnInstall = Sql.YesNoType.yes;
108 }
109
110 if (SqlCompiler.DbDropOnUninstall == (attributes & SqlCompiler.DbDropOnUninstall))
111 {
112 sqlDatabase.DropOnUninstall = Sql.YesNoType.yes;
113 }
114
115 if (SqlCompiler.DbContinueOnError == (attributes & SqlCompiler.DbContinueOnError))
116 {
117 sqlDatabase.ContinueOnError = Sql.YesNoType.yes;
118 }
119
120 if (SqlCompiler.DbDropOnInstall == (attributes & SqlCompiler.DbDropOnInstall))
121 {
122 sqlDatabase.DropOnInstall = Sql.YesNoType.yes;
123 }
124
125 if (SqlCompiler.DbCreateOnUninstall == (attributes & SqlCompiler.DbCreateOnUninstall))
126 {
127 sqlDatabase.CreateOnUninstall = Sql.YesNoType.yes;
128 }
129
130 if (SqlCompiler.DbConfirmOverwrite == (attributes & SqlCompiler.DbConfirmOverwrite))
131 {
132 sqlDatabase.ConfirmOverwrite = Sql.YesNoType.yes;
133 }
134
135 if (SqlCompiler.DbCreateOnReinstall == (attributes & SqlCompiler.DbCreateOnReinstall))
136 {
137 sqlDatabase.CreateOnReinstall = Sql.YesNoType.yes;
138 }
139
140 if (SqlCompiler.DbDropOnReinstall == (attributes & SqlCompiler.DbDropOnReinstall))
141 {
142 sqlDatabase.DropOnReinstall = Sql.YesNoType.yes;
143 }
144 }
145
146 if (null != row[4])
147 {
148 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[4]);
149
150 if (null != component)
151 {
152 component.AddChild(sqlDatabase);
153 }
154 else
155 {
156 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[4], "Component"));
157 }
158 }
159 else
160 {
161 this.Core.RootElement.AddChild(sqlDatabase);
162 }
163 this.Core.IndexElement(row, sqlDatabase);
164 }
165 }
166
167 /// <summary>
168 /// Decompile the SqlScript table.
169 /// </summary>
170 /// <param name="table">The table to decompile.</param>
171 private void DecompileSqlScriptTable(Table table)
172 {
173 foreach (Row row in table.Rows)
174 {
175 Sql.SqlScript sqlScript = new Sql.SqlScript();
176
177 sqlScript.Id = (string)row[0];
178
179 // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables
180
181 sqlScript.BinaryKey = (string)row[3];
182
183 if (null != row[4])
184 {
185 sqlScript.User = (string)row[4];
186 }
187
188 int attributes = (int)row[5];
189
190 if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError))
191 {
192 sqlScript.ContinueOnError = Sql.YesNoType.yes;
193 }
194
195 if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall))
196 {
197 sqlScript.ExecuteOnInstall = Sql.YesNoType.yes;
198 }
199
200 if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall))
201 {
202 sqlScript.ExecuteOnReinstall = Sql.YesNoType.yes;
203 }
204
205 if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall))
206 {
207 sqlScript.ExecuteOnUninstall = Sql.YesNoType.yes;
208 }
209
210 if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall)))
211 {
212 sqlScript.RollbackOnInstall = Sql.YesNoType.yes;
213 }
214
215 if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall)))
216 {
217 sqlScript.RollbackOnReinstall = Sql.YesNoType.yes;
218 }
219
220 if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall)))
221 {
222 sqlScript.RollbackOnUninstall = Sql.YesNoType.yes;
223 }
224
225 if (null != row[6])
226 {
227 sqlScript.Sequence = (int)row[6];
228 }
229
230 this.Core.IndexElement(row, sqlScript);
231 }
232 }
233
234 /// <summary>
235 /// Decompile the SqlString table.
236 /// </summary>
237 /// <param name="table">The table to decompile.</param>
238 private void DecompileSqlStringTable(Table table)
239 {
240 foreach (Row row in table.Rows)
241 {
242 Sql.SqlString sqlString = new Sql.SqlString();
243
244 sqlString.Id = (string)row[0];
245
246 // the Db_ and Component_ columns are handled in FinalizeSqlScriptAndSqlStringTables
247
248 sqlString.SQL = (string)row[3];
249
250 if (null != row[4])
251 {
252 sqlString.User = (string)row[4];
253 }
254
255 int attributes = (int)row[5];
256
257 if (SqlCompiler.SqlContinueOnError == (attributes & SqlCompiler.SqlContinueOnError))
258 {
259 sqlString.ContinueOnError = Sql.YesNoType.yes;
260 }
261
262 if (SqlCompiler.SqlExecuteOnInstall == (attributes & SqlCompiler.SqlExecuteOnInstall))
263 {
264 sqlString.ExecuteOnInstall = Sql.YesNoType.yes;
265 }
266
267 if (SqlCompiler.SqlExecuteOnReinstall == (attributes & SqlCompiler.SqlExecuteOnReinstall))
268 {
269 sqlString.ExecuteOnReinstall = Sql.YesNoType.yes;
270 }
271
272 if (SqlCompiler.SqlExecuteOnUninstall == (attributes & SqlCompiler.SqlExecuteOnUninstall))
273 {
274 sqlString.ExecuteOnUninstall = Sql.YesNoType.yes;
275 }
276
277 if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnInstall)))
278 {
279 sqlString.RollbackOnInstall = Sql.YesNoType.yes;
280 }
281
282 if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnReinstall)))
283 {
284 sqlString.RollbackOnReinstall = Sql.YesNoType.yes;
285 }
286
287 if ((SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall) == (attributes & (SqlCompiler.SqlRollback | SqlCompiler.SqlExecuteOnUninstall)))
288 {
289 sqlString.RollbackOnUninstall = Sql.YesNoType.yes;
290 }
291
292 if (null != row[6])
293 {
294 sqlString.Sequence = (int)row[6];
295 }
296
297 this.Core.IndexElement(row, sqlString);
298 }
299 }
300
301 /// <summary>
302 /// Finalize the SqlFileSpec table.
303 /// </summary>
304 /// <param name="tables">The collection of all tables.</param>
305 /// <remarks>
306 /// Since rows of the SqlFileSpec table are represented by either
307 /// the SqlFileSpec or SqlLogFileSpec depending upon the context in
308 /// which they are used in the SqlDatabase table, decompilation of this
309 /// table must occur after the SqlDatbase parents are decompiled.
310 /// </remarks>
311 private void FinalizeSqlFileSpecTable(TableIndexedCollection tables)
312 {
313 Table sqlDatabaseTable = tables["SqlDatabase"];
314 Table sqlFileSpecTable = tables["SqlFileSpec"];
315
316 if (null != sqlDatabaseTable && null != sqlFileSpecTable)
317 {
318 Hashtable sqlFileSpecRows = new Hashtable();
319
320 // index each SqlFileSpec row by its primary key
321 foreach (Row row in sqlFileSpecTable.Rows)
322 {
323 sqlFileSpecRows.Add(row[0], row);
324 }
325
326 // create the necessary SqlFileSpec and SqlLogFileSpec elements for each row
327 foreach (Row row in sqlDatabaseTable.Rows)
328 {
329 Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(row);
330
331 if (null != row[6])
332 {
333 Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[6]];
334
335 if (null != sqlFileSpecRow)
336 {
337 Sql.SqlFileSpec sqlFileSpec = new Sql.SqlFileSpec();
338
339 sqlFileSpec.Id = (string)sqlFileSpecRow[0];
340
341 if (null != sqlFileSpecRow[1])
342 {
343 sqlFileSpec.Name = (string)sqlFileSpecRow[1];
344 }
345
346 sqlFileSpec.Filename = (string)sqlFileSpecRow[2];
347
348 if (null != sqlFileSpecRow[3])
349 {
350 sqlFileSpec.Size = (string)sqlFileSpecRow[3];
351 }
352
353 if (null != sqlFileSpecRow[4])
354 {
355 sqlFileSpec.MaxSize = (string)sqlFileSpecRow[4];
356 }
357
358 if (null != sqlFileSpecRow[5])
359 {
360 sqlFileSpec.GrowthSize = (string)sqlFileSpecRow[5];
361 }
362
363 sqlDatabase.AddChild(sqlFileSpec);
364 }
365 else
366 {
367 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_", (string)row[6], "SqlFileSpec"));
368 }
369 }
370
371 if (null != row[7])
372 {
373 Row sqlFileSpecRow = (Row)sqlFileSpecRows[row[7]];
374
375 if (null != sqlFileSpecRow)
376 {
377 Sql.SqlLogFileSpec sqlLogFileSpec = new Sql.SqlLogFileSpec();
378
379 sqlLogFileSpec.Id = (string)sqlFileSpecRow[0];
380
381 if (null != sqlFileSpecRow[1])
382 {
383 sqlLogFileSpec.Name = (string)sqlFileSpecRow[1];
384 }
385
386 sqlLogFileSpec.Filename = (string)sqlFileSpecRow[2];
387
388 if (null != sqlFileSpecRow[3])
389 {
390 sqlLogFileSpec.Size = (string)sqlFileSpecRow[3];
391 }
392
393 if (null != sqlFileSpecRow[4])
394 {
395 sqlLogFileSpec.MaxSize = (string)sqlFileSpecRow[4];
396 }
397
398 if (null != sqlFileSpecRow[5])
399 {
400 sqlLogFileSpec.GrowthSize = (string)sqlFileSpecRow[5];
401 }
402
403 sqlDatabase.AddChild(sqlLogFileSpec);
404 }
405 else
406 {
407 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlDatabaseTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "FileSpec_Log", (string)row[7], "SqlFileSpec"));
408 }
409 }
410 }
411 }
412 }
413
414 /// <summary>
415 /// Finalize the SqlScript table.
416 /// </summary>
417 /// <param name="tables">The collection of all tables.</param>
418 /// <remarks>
419 /// The SqlScript and SqlString tables contain a foreign key into the SqlDatabase
420 /// and Component tables. Depending upon the parent of the SqlDatabase
421 /// element, the SqlScript and SqlString elements are nested under either the
422 /// SqlDatabase or the Component element.
423 /// </remarks>
424 private void FinalizeSqlScriptAndSqlStringTables(TableIndexedCollection tables)
425 {
426 Table sqlDatabaseTable = tables["SqlDatabase"];
427 Table sqlScriptTable = tables["SqlScript"];
428 Table sqlStringTable = tables["SqlString"];
429
430 Hashtable sqlDatabaseRows = new Hashtable();
431
432 // index each SqlDatabase row by its primary key
433 if (null != sqlDatabaseTable)
434 {
435 foreach (Row row in sqlDatabaseTable.Rows)
436 {
437 sqlDatabaseRows.Add(row[0], row);
438 }
439 }
440
441 if (null != sqlScriptTable)
442 {
443 foreach (Row row in sqlScriptTable.Rows)
444 {
445 Sql.SqlScript sqlScript = (Sql.SqlScript)this.Core.GetIndexedElement(row);
446
447 Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]];
448 string databaseComponent = (string)sqlDatabaseRow[4];
449
450 // determine if the SqlScript element should be nested under the database or another component
451 if (null != databaseComponent && databaseComponent == (string)row[2])
452 {
453 Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow);
454
455 sqlDatabase.AddChild(sqlScript);
456 }
457 else // nest under the component of the SqlDatabase row
458 {
459 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
460
461 // set the Database value
462 sqlScript.SqlDb = (string)row[1];
463
464 if (null != component)
465 {
466 component.AddChild(sqlScript);
467 }
468 else
469 {
470 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlScriptTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
471 }
472 }
473 }
474 }
475
476 if (null != sqlStringTable)
477 {
478 foreach (Row row in sqlStringTable.Rows)
479 {
480 Sql.SqlString sqlString = (Sql.SqlString)this.Core.GetIndexedElement(row);
481
482 Row sqlDatabaseRow = (Row)sqlDatabaseRows[row[1]];
483 string databaseComponent = (string)sqlDatabaseRow[4];
484
485 // determine if the SqlScript element should be nested under the database or another component
486 if (null != databaseComponent && databaseComponent == (string)row[2])
487 {
488 Sql.SqlDatabase sqlDatabase = (Sql.SqlDatabase)this.Core.GetIndexedElement(sqlDatabaseRow);
489
490 sqlDatabase.AddChild(sqlString);
491 }
492 else // nest under the component of the SqlDatabase row
493 {
494 Wix.Component component = (Wix.Component)this.Core.GetIndexedElement("Component", (string)row[2]);
495
496 // set the Database value
497 sqlString.SqlDb = (string)row[1];
498
499 if (null != component)
500 {
501 component.AddChild(sqlString);
502 }
503 else
504 {
505 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, sqlStringTable.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "Component_", (string)row[2], "Component"));
506 }
507 }
508 }
509 }
510 }
511 }
512}
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 @@
1// 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.
2
3namespace WixToolset.Extensions
4{
5 public sealed class SqlErrors
6 {
7
8 private SqlErrors()
9 {
10 }
11
12 public static MessageEventArgs IllegalAttributeWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName)
13 {
14 return new SqlErrorEventArgs(sourceLineNumbers, 5100, "SqlErrors_IllegalAttributeWithoutComponent_1", elementName, attributeName);
15 }
16
17 public static MessageEventArgs IllegalElementWithoutComponent(SourceLineNumber sourceLineNumbers, string elementName)
18 {
19 return new SqlErrorEventArgs(sourceLineNumbers, 5101, "SqlErrors_IllegalElementWithoutComponent_1", elementName);
20 }
21
22 public static MessageEventArgs OneOfAttributesRequiredUnderComponent(SourceLineNumber sourceLineNumbers, string elementName, string attributeName1, string attributeName2, string attributeName3, string attributeName4)
23 {
24 return new SqlErrorEventArgs(sourceLineNumbers, 5102, "SqlErrors_OneOfAttributesRequiredUnderComponent_1", elementName, attributeName1, attributeName2, attributeName3, attributeName4);
25 }
26
27 public static MessageEventArgs DeprecatedBinaryChildElement(SourceLineNumber sourceLineNumbers, string elementName)
28 {
29 return new SqlErrorEventArgs(sourceLineNumbers, 5103, "SqlErrors_DeprecatedBinaryChildElement_1", elementName);
30 }
31 }
32} \ 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 @@
1// 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.
2
3namespace WixToolset.Extensions
4{
5 using System;
6 using System.Reflection;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9
10 /// <summary>
11 /// The WiX Toolset SQL Server Extension.
12 /// </summary>
13 public sealed class SqlExtensionData : ExtensionData
14 {
15 /// <summary>
16 /// Gets the default culture.
17 /// </summary>
18 /// <value>The default culture.</value>
19 public override string DefaultCulture
20 {
21 get { return "en-us"; }
22 }
23
24 /// <summary>
25 /// Gets the optional table definitions for this extension.
26 /// </summary>
27 /// <value>The optional table definitions for this extension.</value>
28 public override TableDefinitionCollection TableDefinitions
29 {
30 get
31 {
32 return SqlExtensionData.GetExtensionTableDefinitions();
33 }
34 }
35
36 /// <summary>
37 /// Gets the library associated with this extension.
38 /// </summary>
39 /// <param name="tableDefinitions">The table definitions to use while loading the library.</param>
40 /// <returns>The loaded library.</returns>
41 public override Library GetLibrary(TableDefinitionCollection tableDefinitions)
42 {
43 return SqlExtensionData.GetExtensionLibrary(tableDefinitions);
44 }
45
46 /// <summary>
47 /// Internal mechanism to access the extension's table definitions.
48 /// </summary>
49 /// <returns>Extension's table definitions.</returns>
50 internal static TableDefinitionCollection GetExtensionTableDefinitions()
51 {
52 return ExtensionData.LoadTableDefinitionHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.tables.xml");
53 }
54
55 /// <summary>
56 /// Internal mechanism to access the extension's library.
57 /// </summary>
58 /// <returns>Extension's library.</returns>
59 internal static Library GetExtensionLibrary(TableDefinitionCollection tableDefinitions)
60 {
61 return ExtensionData.LoadLibraryHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.sql.wixlib", tableDefinitions);
62 }
63 }
64}
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<xs:schema xmlns:html="http://www.w3.org/1999/xhtml"
6 xmlns:wix="http://wixtoolset.org/schemas/v4/wxs"
7 xmlns:xs="http://www.w3.org/2001/XMLSchema"
8 xmlns:xse=" http://wixtoolset.org/schemas/XmlSchemaExtension"
9 targetNamespace="http://wixtoolset.org/schemas/v4/wxs/sql"
10 xmlns="http://wixtoolset.org/schemas/v4/wxs/sql">
11 <xs:annotation>
12 <xs:documentation>
13 The source code schema for the WiX Toolset SQL Server Extension.
14 </xs:documentation>
15 </xs:annotation>
16
17 <xs:import namespace="http://wixtoolset.org/schemas/v4/wxs" />
18
19 <xs:element name="SqlDatabase">
20 <xs:annotation>
21 <xs:appinfo>
22 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
23 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Fragment" />
24 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Module" />
25 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Product" />
26 <xse:remarks>
27 <html:dl>
28 <html:dd>Nesting SqlDatabase under a Component element will result in a SqlDatabase being installed to the machine as the package is installed.</html:dd>
29 <html:dd>
30 Nesting SqlDatabase under Product, Fragment, or Module
31 results in a database "locator" record being created in
32 the SqlDatabase table. This means that the database
33 itself is neither installed nor uninstalled by the MSI
34 package. It does make the database available for referencing
35 from a SqlString or SqlScript record. This allows MSI to install
36 SqlScripts or SqlStrings to already existing databases on the machine.
37 The install will fail if the database does not exist in these cases.
38 </html:dd>
39 <html:dd>
40 The User attribute references credentials specified in a User element.
41 If a user is not specified then Windows Authentication will be used by default
42 using the credentials of the user performing the install to execute sql
43 strings, etc.
44 </html:dd>
45 </html:dl>
46 </xse:remarks>
47 <xse:seeAlso namespace="http://schemas.microsoft.com/wix/UtilExtension" ref="User"/>
48 </xs:appinfo>
49 <xs:documentation>SQL Database</xs:documentation>
50 </xs:annotation>
51 <xs:complexType>
52 <xs:choice minOccurs="0" maxOccurs="unbounded">
53 <xs:sequence>
54 <xs:element ref="SqlFileSpec" minOccurs="0"/>
55 <xs:element ref="SqlLogFileSpec" minOccurs="0"/>
56 </xs:sequence>
57 <xs:element ref="SqlScript"/>
58 <xs:element ref="SqlString"/>
59 </xs:choice>
60 <xs:attribute name="Id" use="required" type="xs:string"/>
61 <xs:attribute name="Server" use="required" type="xs:string">
62 </xs:attribute>
63 <xs:attribute name="Instance" type="xs:string">
64 </xs:attribute>
65 <xs:attribute name="Database" use="required" type="xs:string">
66 <xs:annotation>
67 <xs:documentation>
68 The name of the database. The value can be a literal value or derived from a
69 Property element using the <html:a href='http://msdn.microsoft.com/library/aa368609.aspx' target='_blank'>Formatted</html:a>
70 syntax.
71 </xs:documentation>
72 </xs:annotation>
73 </xs:attribute>
74 <xs:attribute name="User" type="xs:string">
75 </xs:attribute>
76 <xs:attribute name="CreateOnInstall" type="YesNoType">
77 </xs:attribute>
78 <xs:attribute name="CreateOnReinstall" type="YesNoType">
79 <xs:annotation>
80 <xs:documentation>
81 Specifies whether to create the database when the associated component is reinstalled. Setting CreateOnInstall to yes does <html:b>not</html:b> imply CreateOnReinstall is set to yes. CreateOnReinstall must be set in addition to CreateOnInstall for it to be created during both install and reinstall.
82 </xs:documentation>
83 </xs:annotation>
84 </xs:attribute>
85 <xs:attribute name="CreateOnUninstall" type="YesNoType">
86 </xs:attribute>
87 <xs:attribute name="DropOnInstall" type="YesNoType">
88 </xs:attribute>
89 <xs:attribute name="DropOnReinstall" type="YesNoType">
90 <xs:annotation>
91 <xs:documentation>
92 Specifies whether to drop the database when the associated component is reinstalled. Setting DropOnInstall to yes does <html:b>not</html:b> imply DropOnReinstall is set to yes. DropOnReinstall must be set in addition to DropOnInstall for it to be dropped during both install and reinstall.
93 </xs:documentation>
94 </xs:annotation>
95 </xs:attribute>
96 <xs:attribute name="DropOnUninstall" type="YesNoType">
97 </xs:attribute>
98 <xs:attribute name="ContinueOnError" type="YesNoType">
99 </xs:attribute>
100 <xs:attribute name="ConfirmOverwrite" type="YesNoType">
101 </xs:attribute>
102 </xs:complexType>
103 </xs:element>
104
105 <xs:element name="SqlFileSpec">
106 <xs:annotation>
107 <xs:documentation>File specification for a Sql database.</xs:documentation>
108 </xs:annotation>
109 <xs:complexType>
110 <xs:attribute name="Id" use="required" type="xs:string">
111 <xs:annotation>
112 <xs:documentation>ID of the file specification.</xs:documentation>
113 </xs:annotation>
114 </xs:attribute>
115 <xs:attribute name="Name" type="xs:string">
116 <xs:annotation>
117 <xs:documentation>Specifies the logical name for the database file.</xs:documentation>
118 </xs:annotation>
119 </xs:attribute>
120 <xs:attribute name="Filename" use="required" type="xs:string">
121 <xs:annotation>
122 <xs:documentation>Specifies the operating-system file name for the database file.</xs:documentation>
123 </xs:annotation>
124 </xs:attribute>
125 <xs:attribute name="Size" type="xs:string">
126 <xs:annotation>
127 <xs:documentation>
128 Specifies the size of the database file. The GB, MB and KB suffixes can be used to specify gigabytes,
129 megabytes or kilobytes. The default is megabytes if no suffix is specified. When a Size is not
130 supplied for a database file, SQL Server uses the size of the primary file in the model database.
131 </xs:documentation>
132 </xs:annotation>
133 </xs:attribute>
134 <xs:attribute name="MaxSize" type="xs:string">
135 <xs:annotation>
136 <xs:documentation>
137 Specifies the maximum size to which the database file can grow. The GB, MB and KB suffixes can be used to
138 to specify gigabytes, megabytes or kilobytes. The default is megabytes if no suffix is specified. If
139 MaxSize is not specified, the file will grow until the disk is full.
140 </xs:documentation>
141 </xs:annotation>
142 </xs:attribute>
143 <xs:attribute name="GrowthSize" type="xs:string">
144 <xs:annotation>
145 <xs:documentation>
146 Specifies the growth increment of the database file. The GB, MB and KB and % suffixes can be used to
147 specify gigabytes, megabytes, kilobytes or a percentage of the current file size to grow. The default is
148 megabytes if no suffix is specified. The default value is 10% if GrowthSize is not specified, and the
149 minimum value is 64 KB. The GrowthSize setting for a file cannot exceed the MaxSize setting.
150 </xs:documentation>
151 </xs:annotation>
152 </xs:attribute>
153 </xs:complexType>
154 </xs:element>
155
156 <xs:element name="SqlLogFileSpec">
157 <xs:annotation>
158 <xs:documentation>File specification for a Sql database.</xs:documentation>
159 </xs:annotation>
160 <xs:complexType>
161 <xs:attribute name="Id" type="xs:string">
162 <xs:annotation>
163 <xs:documentation>ID of the log file specification.</xs:documentation>
164 </xs:annotation>
165 </xs:attribute>
166 <xs:attribute name="Name" type="xs:string">
167 <xs:annotation>
168 <xs:documentation>Specifies the logical name for the log file.</xs:documentation>
169 </xs:annotation>
170 </xs:attribute>
171 <xs:attribute name="Filename" type="xs:string">
172 <xs:annotation>
173 <xs:documentation>Specifies the operating-system file name for the log file.</xs:documentation>
174 </xs:annotation>
175 </xs:attribute>
176 <xs:attribute name="Size" type="xs:string">
177 <xs:annotation>
178 <xs:documentation>
179 Specifies the size of the log file. The GB, MB and KB suffixes can be used to specify gigabytes,
180 megabytes or kilobytes. The default is megabytes if no suffix is specified. When a Size is not
181 supplied for a log file, SQL Server makes the file 1 MB.
182 </xs:documentation>
183 </xs:annotation>
184 </xs:attribute>
185 <xs:attribute name="MaxSize" type="xs:string">
186 <xs:annotation>
187 <xs:documentation>
188 Specifies the maximum size to which the log file can grow. The GB, MB and KB suffixes can be used to
189 to specify gigabytes, megabytes or kilobytes. The default is megabytes if no suffix is specified. If
190 MaxSize is not specified, the file will grow until the disk is full.
191 </xs:documentation>
192 </xs:annotation>
193 </xs:attribute>
194 <xs:attribute name="GrowthSize" type="xs:string">
195 <xs:annotation>
196 <xs:documentation>
197 Specifies the growth increment of the log file. The GB, MB and KB and % suffixes can be used to
198 specify gigabytes, megabytes, kilobytes or a percentage of the current file size to grow. The default is
199 megabytes if no suffix is specified. The default value is 10% if GrowthSize is not specified, and the
200 minimum value is 64 KB. The GrowthSize setting for a file cannot exceed the MaxSize setting.
201 </xs:documentation>
202 </xs:annotation>
203 </xs:attribute>
204 </xs:complexType>
205 </xs:element>
206
207 <xs:element name="SqlScript">
208 <xs:annotation>
209 <xs:appinfo>
210 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
211 </xs:appinfo>
212 <xs:documentation>SQL Script</xs:documentation>
213 </xs:annotation>
214 <xs:complexType>
215 <xs:attribute name="Id" use="required" type="xs:string"/>
216 <xs:attribute name="SqlDb" type="xs:string">
217 <xs:annotation>
218 <xs:documentation>required when not child of SqlDatabase</xs:documentation>
219 </xs:annotation>
220 </xs:attribute>
221 <xs:attribute name="User" type="xs:string">
222 </xs:attribute>
223 <xs:attribute name="BinaryKey" type="xs:string" use="required">
224 <xs:annotation>
225 <xs:documentation>Reference to Binary stream that contains the SQL script to execute.</xs:documentation>
226 </xs:annotation>
227 </xs:attribute>
228 <xs:attribute name="ExecuteOnInstall" type="YesNoType">
229 <xs:annotation>
230 <xs:documentation>Specifies to execute the script when the associated component is installed. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes.</xs:documentation>
231 </xs:annotation>
232 </xs:attribute>
233 <xs:attribute name="ExecuteOnReinstall" type="YesNoType">
234 <xs:annotation>
235 <xs:documentation>Specifies whether to execute the script when the associated component is reinstalled. Setting ExecuteOnInstall to yes does <html:b>not</html:b> 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.</xs:documentation>
236 </xs:annotation>
237 </xs:attribute>
238 <xs:attribute name="ExecuteOnUninstall" type="YesNoType">
239 <xs:annotation>
240 <xs:documentation>Specifies to execute the script when the associated component is uninstalled. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes.</xs:documentation>
241 </xs:annotation>
242 </xs:attribute>
243 <xs:attribute name="RollbackOnInstall" type="YesNoType">
244 <xs:annotation>
245 <xs:documentation>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.</xs:documentation>
246 </xs:annotation>
247 </xs:attribute>
248 <xs:attribute name="RollbackOnReinstall" type="YesNoType">
249 <xs:annotation>
250 <xs:documentation>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.</xs:documentation>
251 </xs:annotation>
252 </xs:attribute>
253 <xs:attribute name="RollbackOnUninstall" type="YesNoType">
254 <xs:annotation>
255 <xs:documentation>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.</xs:documentation>
256 </xs:annotation>
257 </xs:attribute>
258 <xs:attribute name="ContinueOnError" type="YesNoType">
259 <xs:annotation>
260 <xs:documentation>Continue executing scripts even if this one fails.</xs:documentation>
261 </xs:annotation>
262 </xs:attribute>
263 <xs:attribute name="Sequence" type="xs:integer">
264 <xs:annotation>
265 <xs:documentation>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.</xs:documentation>
266 </xs:annotation>
267 </xs:attribute>
268 </xs:complexType>
269 </xs:element>
270
271 <xs:element name="SqlString">
272 <xs:annotation>
273 <xs:appinfo>
274 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="Component" />
275 </xs:appinfo>
276 <xs:documentation>SQL String</xs:documentation>
277 </xs:annotation>
278 <xs:complexType>
279 <xs:attribute name="Id" use="required" type="xs:string">
280 </xs:attribute>
281 <xs:attribute name="SQL" use="required" type="xs:string">
282 </xs:attribute>
283 <xs:attribute name="User" type="xs:string">
284 </xs:attribute>
285 <xs:attribute name="SqlDb" type="xs:string">
286 </xs:attribute>
287 <xs:attribute name="ExecuteOnInstall" type="YesNoType">
288 <xs:annotation>
289 <xs:documentation>Specifies to execute the string when the associated component is installed. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes.</xs:documentation>
290 </xs:annotation>
291 </xs:attribute>
292 <xs:attribute name="ExecuteOnReinstall" type="YesNoType">
293 <xs:annotation>
294 <xs:documentation>
295 Specifies whether to execute the string when the associated component is reinstalled. Setting ExecuteOnInstall to yes does <html:b>not</html:b> 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.
296 </xs:documentation>
297 </xs:annotation>
298 </xs:attribute>
299 <xs:attribute name="ExecuteOnUninstall" type="YesNoType">
300 <xs:annotation>
301 <xs:documentation>Specifies to execute the string when the associated component is uninstalled. This attribute is mutually exclusive with the RollbackOnInstall, RollbackOnReinstall and RollbackOnUninstall attributes.</xs:documentation>
302 </xs:annotation>
303 </xs:attribute>
304 <xs:attribute name="RollbackOnInstall" type="YesNoType">
305 <xs:annotation>
306 <xs:documentation>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.</xs:documentation>
307 </xs:annotation>
308 </xs:attribute>
309 <xs:attribute name="RollbackOnReinstall" type="YesNoType">
310 <xs:annotation>
311 <xs:documentation>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.</xs:documentation>
312 </xs:annotation>
313 </xs:attribute>
314 <xs:attribute name="RollbackOnUninstall" type="YesNoType">
315 <xs:annotation>
316 <xs:documentation>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.</xs:documentation>
317 </xs:annotation>
318 </xs:attribute>
319 <xs:attribute name="ContinueOnError" type="YesNoType">
320 <xs:annotation>
321 <xs:documentation>Continue executing strings even if this one fails.</xs:documentation>
322 </xs:annotation>
323 </xs:attribute>
324 <xs:attribute name="Sequence" type="xs:integer">
325 <xs:annotation>
326 <xs:documentation>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.</xs:documentation>
327 </xs:annotation>
328 </xs:attribute>
329 </xs:complexType>
330 </xs:element>
331
332 <xs:simpleType name="YesNoType">
333 <xs:annotation>
334 <xs:documentation>Values of this type will either be "yes" or "no".</xs:documentation>
335 </xs:annotation>
336 <xs:restriction base='xs:NMTOKEN'>
337 <xs:enumeration value="no"/>
338 <xs:enumeration value="yes"/>
339 </xs:restriction>
340 </xs:simpleType>
341
342</xs:schema>
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 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<!-- 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. -->
3
4
5<tableDefinitions xmlns="http://wixtoolset.org/schemas/v4/wi/tables">
6 <tableDefinition name="SqlDatabase" createSymbols="yes">
7 <columnDefinition name="SqlDb" type="string" length="72" primaryKey="yes" modularize="column"
8 category="identifier" description="Primary key, non-localized token"/>
9 <columnDefinition name="Server" type="string" length="255" nullable="yes"
10 category="formatted" description="Primary key, name of server running SQL Server"/>
11 <columnDefinition name="Instance" type="string" length="255" nullable="yes"
12 category="formatted" description="Primary key, name of SQL Server instance"/>
13 <!-- TODO: change the Database column length to "128" in WiX v4.0 when we can put in breaking changes -->
14 <columnDefinition name="Database" type="string" length="255"
15 category="formatted" description="Primary key, name of database in a SQL Server"/>
16 <columnDefinition name="Component_" type="string" length="72" modularize="column" nullable="yes"
17 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key, Component used to determine install state "/>
18 <columnDefinition name="User_" type="string" length="72" nullable="yes" modularize="column"
19 keyTable="User" keyColumn="1" category="identifier" description="Foreign key, User used to log into database"/>
20 <columnDefinition name="FileSpec_" type="string" length="72" nullable="yes" modularize="column"
21 keyTable="SqlFileSpec" keyColumn="1" category="identifier" description="Foreign key referencing SqlFileSpec."/>
22 <columnDefinition name="FileSpec_Log" type="string" length="72" nullable="yes" modularize="column"
23 keyTable="SqlFileSpec" keyColumn="1" category="identifier" description="Foreign key referencing SqlFileSpec."/>
24 <columnDefinition name="Attributes" type="number" length="2" nullable="yes"
25 minValue="0" maxValue="255" description="1 == create on install, 2 == drop on uninstall, 4 == continue on error, 8 == drop on install, 16 == create on uninstall, 32 == confirm update existing table, 64 == create on reinstall, 128 == drop on reinstall" />
26 </tableDefinition>
27 <tableDefinition name="SqlFileSpec" createSymbols="yes">
28 <columnDefinition name="FileSpec" type="string" length="72" primaryKey="yes" modularize="column"
29 category="identifier" description="Primary key, non-localized token"/>
30 <columnDefinition name="Name" type="string" length="255" modularize="property"
31 category="formatted" description="Logical name of filespec"/>
32 <columnDefinition name="Filename" type="string" length="255" modularize="property"
33 category="formatted" description="Filename to use (path must exist)"/>
34 <columnDefinition name="Size" type="string" length="72" nullable="yes" modularize="property"
35 category="formatted" description="Initial size for file"/>
36 <columnDefinition name="MaxSize" type="string" length="72" nullable="yes" modularize="property"
37 category="formatted" description="Maximum size for file"/>
38 <columnDefinition name="GrowthSize" type="string" length="72" nullable="yes" modularize="property"
39 category="formatted" description="Size file should grow when necessary"/>
40 </tableDefinition>
41 <tableDefinition name="SqlScript">
42 <columnDefinition name="Script" type="string" length="72" primaryKey="yes"
43 category="identifier" description="Primary key, non-localized token"/>
44 <columnDefinition name="SqlDb_" type="string" length="72" modularize="column"
45 keyTable="SqlDatabase" keyColumn="1" category="identifier" description="Foreign key, SQL Server key"/>
46 <columnDefinition name="Component_" type="string" length="72" modularize="column"
47 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key, Component used to determine install state"/>
48 <columnDefinition name="ScriptBinary_" type="string" length="72" modularize="column"
49 keyTable="Binary" keyColumn="1" category="identifier" description="Foreign key, Binary stream that contains SQL Script to execute"/>
50 <columnDefinition name="User_" type="string" length="72" nullable="yes" modularize="column"
51 keyTable="User" keyColumn="1" category="identifier" description="Foreign key, User used to log into database"/>
52 <columnDefinition name="Attributes" type="number" length="2"
53 set="1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31" description="1 == execute on install, 2 == execute on uninstall, 4 == continue on error, 8 == rollback on install, 16 == rollback on uninstall"/>
54 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
55 description="Order to execute SQL Queries in"/>
56 </tableDefinition>
57 <tableDefinition name="SqlString">
58 <columnDefinition name="String" type="string" length="72" modularize="column" primaryKey="yes"
59 category="identifier" description="Id for the SqlString" />
60 <columnDefinition name="SqlDb_" type="string" length="72" modularize="column"
61 keyTable="SqlDatabase" keyColumn="1" category="identifier" description="Foreign key, SQL Server key"/>
62 <columnDefinition name="Component_" type="string" length="72" modularize="column"
63 keyTable="Component" keyColumn="1" category="identifier" description="Foreign key, Component used to determine install state"/>
64 <columnDefinition name="SQL" type="string" length="0"
65 category="formatted" description="SQL query to execute" escapeIdtCharacters="yes"/>
66 <columnDefinition name="User_" type="string" length="72" nullable="yes" modularize="column"
67 keyTable="User" keyColumn="1" category="identifier" description="Foreign key, User used to log into database"/>
68 <columnDefinition name="Attributes" type="number" length="2"
69 set="1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;30;31" description="1 == execute on install, 2 == execute on uninstall, 4 == continue on error, 8 == rollback on install, 16 == rollback on uninstall"/>
70 <columnDefinition name="Sequence" type="number" length="2" nullable="yes"
71 description="Order to execute SQL Queries in"/>
72 </tableDefinition>
73</tableDefinitions>
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 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<!-- 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. -->
3
4
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 <?include caerr.wxi ?>
7
8 <!-- Server Custom Action Definitions -->
9
10 <Fragment>
11 <UI>
12 <Error Id="$(var.msierrSQLFailedCreateDatabase)">!(loc.msierrSQLFailedCreateDatabase)</Error>
13 <Error Id="$(var.msierrSQLFailedDropDatabase)">!(loc.msierrSQLFailedDropDatabase)</Error>
14 <Error Id="$(var.msierrSQLFailedConnectDatabase)">!(loc.msierrSQLFailedConnectDatabase)</Error>
15 <Error Id="$(var.msierrSQLFailedExecString)">!(loc.msierrSQLFailedExecString)</Error>
16 <Error Id="$(var.msierrSQLDatabaseAlreadyExists)">!(loc.msierrSQLDatabaseAlreadyExists)</Error>
17
18 <ProgressText Action="InstallSqlData">!(loc.ConfigureSql)</ProgressText>
19 <ProgressText Action="UninstallSqlData">!(loc.ConfigureSql)</ProgressText>
20 <ProgressText Action="CreateDatabase">!(loc.CreateDatabase)</ProgressText>
21 <ProgressText Action="DropDatabase">!(loc.DropDatabase)</ProgressText>
22 <ProgressText Action="ExecuteSqlStrings">!(loc.ExecuteSqlStrings)</ProgressText>
23 <ProgressText Action="RollbackExecuteSqlStrings">!(loc.RollbackExecuteSqlStrings)</ProgressText>
24 </UI>
25
26 <!-- The SQL custom actions should impersonate the user because the user"s cridentials are used when connected to the database if none are provided -->
27 <CustomAction Id="InstallSqlData" BinaryKey="ScaSchedule2" DllEntry="InstallSqlData" Execute="immediate" Return="check" />
28 <CustomAction Id="UninstallSqlData" BinaryKey="ScaSchedule2" DllEntry="UninstallSqlData" Execute="immediate" Return="check" />
29 <CustomAction Id="CreateDatabase" BinaryKey="ScaExecute2" DllEntry="CreateDatabase" Execute="deferred" Return="check" HideTarget="yes" SuppressModularization="yes" TerminalServerAware="yes" />
30 <CustomAction Id="RollbackCreateDatabase" BinaryKey="ScaExecute2" DllEntry="DropDatabase" Execute="rollback" Return="check" HideTarget="yes" SuppressModularization="yes" TerminalServerAware="yes" />
31 <CustomAction Id="DropDatabase" BinaryKey="ScaExecute2" DllEntry="DropDatabase" Execute="deferred" Return="check" HideTarget="yes" SuppressModularization="yes" TerminalServerAware="yes" />
32 <CustomAction Id="ExecuteSqlStrings" BinaryKey="ScaExecute2" DllEntry="ExecuteSqlStrings" Execute="deferred" Return="check" HideTarget="yes" SuppressModularization="yes" TerminalServerAware="yes" />
33 <CustomAction Id="RollbackExecuteSqlStrings" BinaryKey="ScaExecute2" DllEntry="ExecuteSqlStrings" Execute="rollback" Return="check" HideTarget="yes" SuppressModularization="yes" TerminalServerAware="yes" />
34
35 <InstallExecuteSequence>
36 <Custom Action="UninstallSqlData" Before="RemoveFiles" Overridable="yes">NOT SKIPUNINSTALLSQLDATA AND VersionNT &gt; 400</Custom>
37 <Custom Action="InstallSqlData" After="InstallFiles" Overridable="yes">NOT SKIPINSTALLSQLDATA AND VersionNT &gt; 400</Custom>
38 </InstallExecuteSequence>
39 </Fragment>
40
41 <!-- Server Custom Action DLL Definitions -->
42 <Fragment>
43 <Binary Id="ScaSchedule2" SourceFile="scasched.dll" />
44 <Binary Id="ScaExecute2" SourceFile="scaexec.dll" />
45 </Fragment>
46</Wix>
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="en-us" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">Fehler [2]: Erstellen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4].</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">Fehler [2]: Löschen der SQL-Datenbank fehlgeschlagen: [3], Fehlerbeschreibung: [4].</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">Verbinden mit der SQL-Datenbank fehlgeschlagen. ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">Fehler [2]: Das Erstellen der SQL Zeichenfolge ist fehlgeschlagen, Fehlerbeschreibung: [3], SQL-Schlüssel: [4] SQL-Zeichenfolge: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">Die Datenbank [3] existiert bereits. Wollen Sie fortfahren?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">Konfiguriere SQL Server</String>
13 <String Id="CreateDatabase" Overridable="yes">Erstelle Datenbanken</String>
14 <String Id="DropDatabase" Overridable="yes">Lösche Datenbanken</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">SQL-Zeichenfolgen werden erstellt</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">SQL-Zeichenfolgen werden zurückgesetzt</String>
17</WixLocalization>
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="en-us" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">Error [2]: failed to create SQL database: [3], error detail: [4].</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">Error [2]: failed to drop SQL database: [3], error detail: [4].</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">Failed to connect to SQL database. ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">Error [2]: failed to execute SQL string, error detail: [3], SQL key: [4] SQL string: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">The database [3] already exists. Do you want to continue?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">Configuring SQL Server</String>
13 <String Id="CreateDatabase" Overridable="yes">Creating Databases</String>
14 <String Id="DropDatabase" Overridable="yes">Dropping Databases</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">Executing SQL Strings</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">Rolling back SQL Strings</String>
17</WixLocalization>
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="es-es" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">Error [2]: falla al crear la base de datos SQL: [3], detalle del error: [4].</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">Error [2]: falla al poner la base de datos SQL: [3], detalle del error: [4].</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">Falla al conectarse con la base de datos SQL. ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">Error [2]: falla al ejecutar la cadena SQL, detalle del error: [3], Clave SQL: [4] Cadena SQL: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">La base de datos [3] ya existe. ¿Desea continuar?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">Configurando SQL Server</String>
13 <String Id="CreateDatabase" Overridable="yes">Creando Bases de Datos</String>
14 <String Id="DropDatabase" Overridable="yes">Colocando Bases de Datos</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">Ejecutando cadenas SQL</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">Revirtiendo cadenas SQL</String>
17</WixLocalization>
18
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="ja-jp" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">エラー [2]: SQL データベース [3] 作成に失敗しました、エラー詳細: [4]。</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">エラー [2]: SQL データベース [3] の削除に失敗しました、エラー詳細: [4]。</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">SQL データベースへ接続できませんでした。 ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">エラー [2]: SQL ストリングの実行に失敗しました、エラー詳細: [3]、 SQL キー: [4] SQL ストリング: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">データベース [3] は既に存在します。続行しますか?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">SQL サーバーを構成しています</String>
13 <String Id="CreateDatabase" Overridable="yes">データベースを作成しています</String>
14 <String Id="DropDatabase" Overridable="yes">データベースを削除しています</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">SQL ストリングを実行しています</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">SQL ストリングをロールバックしています</String>
17</WixLocalization>
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="pl-pl" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">Błąd [2]: nie udało się utworzyć bazy danych: [3]. Szczegóły błędu: [4].</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">Błąd [2]: nie udało się usunąć bazy danych: [3]. Szczegóły błędu: [4].</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">Nie udało się połączyć z bazą danych. ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">Błąd [2]: nie udało się wykonać zapytania SQL. Szczegóły błędu: [3], klucz: [4] zapytanie SQL: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">Baza danych [3] już istnieje. Czy chcesz kontynuować?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">Konfigurowanie programu SQL Server</String>
13 <String Id="CreateDatabase" Overridable="yes">Tworzenie baz danych</String>
14 <String Id="DropDatabase" Overridable="yes">Usuwanie baz danych</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">Wykonywanie zapytań SQL</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">Cofanie zapytań SQL</String>
17</WixLocalization>
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="pt-br" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">Error [2]: falha ao criar o Banco de Dados: [3], detalhes: [4].</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">Error [2]: falha ao remover o Banco de Dados: [3], detalhes: [4].</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">Falhou a ligação ao Banco de Dados. ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">O Banco de Dados [3] já existe. Deseja continuar?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">Configurando o Servidor de SQL</String>
13 <String Id="CreateDatabase" Overridable="yes">Criando os Bancos de Dados</String>
14 <String Id="DropDatabase" Overridable="yes">Removendo os Bancos de Dados</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">Executando comandos de SQL</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">Revertendo os comandos de SQL</String>
17</WixLocalization>
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 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4
5<WixLocalization Culture="pt-pt" xmlns="http://wixtoolset.org/schemas/v4/wxl">
6 <String Id="msierrSQLFailedCreateDatabase" Overridable="yes">Error [2]: falha ao criar a Base de Dados: [3], detalhes: [4].</String>
7 <String Id="msierrSQLFailedDropDatabase" Overridable="yes">Error [2]: falha ao remover a Base de Dados: [3], detalhes: [4].</String>
8 <String Id="msierrSQLFailedConnectDatabase" Overridable="yes">Falhou a ligação à Base de Dados. ([2] [3] [4] [5])</String>
9 <String Id="msierrSQLFailedExecString" Overridable="yes">Erro [2]: falha ao executar o comando de SQL, detalhes: [3], Comando: [4] Conteúdo: [5]</String>
10 <String Id="msierrSQLDatabaseAlreadyExists" Overridable="yes">A Base de Dados [3] já existe. Deseja continuar?</String>
11
12 <String Id="ConfigureSql" Overridable="yes">Configurar o Servidor de SQL</String>
13 <String Id="CreateDatabase" Overridable="yes">Criar as Bases de Dados</String>
14 <String Id="DropDatabase" Overridable="yes">Remover as Bases de Dados</String>
15 <String Id="ExecuteSqlStrings" Overridable="yes">Executar comandos de SQL</String>
16 <String Id="RollbackExecuteSqlStrings" Overridable="yes">Reverter os comandos de SQL</String>
17</WixLocalization>