aboutsummaryrefslogtreecommitdiff
path: root/src/wixext/SqlDecompiler.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/wixext/SqlDecompiler.cs')
-rw-r--r--src/wixext/SqlDecompiler.cs512
1 files changed, 512 insertions, 0 deletions
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}