aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/Unbind
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2020-01-13 09:10:13 -0800
committerRob Mensching <rob@firegiant.com>2020-01-13 14:19:45 -0800
commit94b941ee95a294228516097c269e27dfa41593ab (patch)
tree208cb36a5a6a3e17f5d458cfaa679d6ca1a76e15 /src/WixToolset.Core.WindowsInstaller/Unbind
parenta2b1235d9c0dfba48b1badac428d89d1137da698 (diff)
downloadwix-94b941ee95a294228516097c269e27dfa41593ab.tar.gz
wix-94b941ee95a294228516097c269e27dfa41593ab.tar.bz2
wix-94b941ee95a294228516097c269e27dfa41593ab.zip
Provide Record enumerator on View that disposes fetched Records
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Unbind')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs325
1 files changed, 154 insertions, 171 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
index 557500e8..fb4b4ee3 100644
--- a/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
+++ b/src/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs
@@ -121,142 +121,125 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
121 // get the normal tables 121 // get the normal tables
122 using (var tablesView = this.Database.OpenExecuteView("SELECT * FROM _Tables")) 122 using (var tablesView = this.Database.OpenExecuteView("SELECT * FROM _Tables"))
123 { 123 {
124 while (true) 124 foreach (var tableRecord in tablesView.Records)
125 { 125 {
126 using (var tableRecord = tablesView.Fetch()) 126 var tableName = tableRecord.GetString(1);
127 {
128 if (null == tableRecord)
129 {
130 break;
131 }
132 127
133 var tableName = tableRecord.GetString(1); 128 using (var tableView = this.Database.OpenExecuteView(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM `{0}`", tableName)))
129 {
130 var tableDefinition = this.GetTableDefinition(tableName, tableView, validationView);
131 var table = new Table(tableDefinition);
134 132
135 using (var tableView = this.Database.OpenExecuteView(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM `{0}`", tableName))) 133 foreach (var rowRecord in tableView.Records)
136 { 134 {
137 var tableDefinition = this.GetTableDefinition(tableName, tableView, validationView); 135 var recordCount = rowRecord.GetFieldCount();
138 var table = new Table(tableDefinition); 136 var row = table.CreateRow(output.SourceLineNumbers);
139 137
140 while (true) 138 for (var i = 0; recordCount > i && row.Fields.Length > i; i++)
141 { 139 {
142 using (var rowRecord = tableView.Fetch()) 140 if (rowRecord.IsNull(i + 1))
143 { 141 {
144 if (null == rowRecord) 142 if (!row.Fields[i].Column.Nullable)
145 { 143 {
146 break; 144 // TODO: display an error for a null value in a non-nullable field OR
145 // display a warning and put an empty string in the value to let the compiler handle it
146 // (the second option is risky because the later code may make certain assumptions about
147 // the contents of a row value)
147 } 148 }
148 149 }
149 var recordCount = rowRecord.GetFieldCount(); 150 else
150 var row = table.CreateRow(output.SourceLineNumbers); 151 {
151 152 switch (row.Fields[i].Column.Type)
152 for (var i = 0; recordCount > i && row.Fields.Length > i; i++)
153 { 153 {
154 if (rowRecord.IsNull(i + 1)) 154 case ColumnType.Number:
155 { 155 var success = false;
156 if (!row.Fields[i].Column.Nullable) 156 var intValue = rowRecord.GetInteger(i + 1);
157 if (row.Fields[i].Column.IsLocalizable)
157 { 158 {
158 // TODO: display an error for a null value in a non-nullable field OR 159 success = row.BestEffortSetField(i, Convert.ToString(intValue, CultureInfo.InvariantCulture));
159 // display a warning and put an empty string in the value to let the compiler handle it
160 // (the second option is risky because the later code may make certain assumptions about
161 // the contents of a row value)
162 } 160 }
163 } 161 else
164 else
165 {
166 switch (row.Fields[i].Column.Type)
167 { 162 {
168 case ColumnType.Number: 163 success = row.BestEffortSetField(i, intValue);
169 var success = false; 164 }
170 var intValue = rowRecord.GetInteger(i + 1);
171 if (row.Fields[i].Column.IsLocalizable)
172 {
173 success = row.BestEffortSetField(i, Convert.ToString(intValue, CultureInfo.InvariantCulture));
174 }
175 else
176 {
177 success = row.BestEffortSetField(i, intValue);
178 }
179 165
180 if (!success) 166 if (!success)
181 { 167 {
182 this.Messaging.Write(WarningMessages.BadColumnDataIgnored(row.SourceLineNumbers, Convert.ToString(intValue, CultureInfo.InvariantCulture), tableName, row.Fields[i].Column.Name)); 168 this.Messaging.Write(WarningMessages.BadColumnDataIgnored(row.SourceLineNumbers, Convert.ToString(intValue, CultureInfo.InvariantCulture), tableName, row.Fields[i].Column.Name));
183 } 169 }
184 break; 170 break;
185 case ColumnType.Object: 171 case ColumnType.Object:
186 var sourceFile = "FILE NOT EXPORTED, USE THE dark.exe -x OPTION TO EXPORT BINARIES"; 172 var sourceFile = "FILE NOT EXPORTED, USE THE dark.exe -x OPTION TO EXPORT BINARIES";
187 173
188 if (null != this.ExportBasePath) 174 if (null != this.ExportBasePath)
189 { 175 {
190 var relativeSourceFile = Path.Combine(tableName, row.GetPrimaryKey('.')); 176 var relativeSourceFile = Path.Combine(tableName, row.GetPrimaryKey('.'));
191 sourceFile = Path.Combine(this.ExportBasePath, relativeSourceFile); 177 sourceFile = Path.Combine(this.ExportBasePath, relativeSourceFile);
192 178
193 // ensure the parent directory exists 179 // ensure the parent directory exists
194 System.IO.Directory.CreateDirectory(Path.Combine(this.ExportBasePath, tableName)); 180 System.IO.Directory.CreateDirectory(Path.Combine(this.ExportBasePath, tableName));
195 181
196 using (var fs = System.IO.File.Create(sourceFile)) 182 using (var fs = System.IO.File.Create(sourceFile))
197 { 183 {
198 int bytesRead; 184 int bytesRead;
199 var buffer = new byte[512]; 185 var buffer = new byte[512];
200 186
201 while (0 != (bytesRead = rowRecord.GetStream(i + 1, buffer, buffer.Length))) 187 while (0 != (bytesRead = rowRecord.GetStream(i + 1, buffer, buffer.Length)))
202 { 188 {
203 fs.Write(buffer, 0, bytesRead); 189 fs.Write(buffer, 0, bytesRead);
204 }
205 } 190 }
206
207 this.exportedFiles.Add(sourceFile);
208 } 191 }
209 192
210 row[i] = sourceFile; 193 this.exportedFiles.Add(sourceFile);
211 break; 194 }
212 default:
213 var value = rowRecord.GetString(i + 1);
214 195
215 switch (row.Fields[i].Column.Category) 196 row[i] = sourceFile;
216 { 197 break;
198 default:
199 var value = rowRecord.GetString(i + 1);
200
201 switch (row.Fields[i].Column.Category)
202 {
217 case ColumnCategory.Guid: 203 case ColumnCategory.Guid:
218 value = value.ToUpper(CultureInfo.InvariantCulture); 204 value = value.ToUpper(CultureInfo.InvariantCulture);
219 break; 205 break;
220 } 206 }
221 207
222 // de-modularize 208 // de-modularize
223 if (!this.SuppressDemodularization && OutputType.Module == output.Type && ColumnModularizeType.None != row.Fields[i].Column.ModularizeType) 209 if (!this.SuppressDemodularization && OutputType.Module == output.Type && ColumnModularizeType.None != row.Fields[i].Column.ModularizeType)
224 { 210 {
225 var modularization = new Regex(@"\.[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}"); 211 var modularization = new Regex(@"\.[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}");
226 212
227 if (null == modularizationGuid) 213 if (null == modularizationGuid)
214 {
215 var match = modularization.Match(value);
216 if (match.Success)
228 { 217 {
229 var match = modularization.Match(value); 218 modularizationGuid = String.Concat('{', match.Value.Substring(1).Replace('_', '-'), '}');
230 if (match.Success)
231 {
232 modularizationGuid = String.Concat('{', match.Value.Substring(1).Replace('_', '-'), '}');
233 }
234 } 219 }
235
236 value = modularization.Replace(value, String.Empty);
237 } 220 }
238 221
239 // escape "$(" for the preprocessor 222 value = modularization.Replace(value, String.Empty);
240 value = value.Replace("$(", "$$("); 223 }
241 224
242 // escape things that look like wix variables 225 // escape "$(" for the preprocessor
243 var matches = Common.WixVariableRegex.Matches(value); 226 value = value.Replace("$(", "$$(");
244 for (var j = matches.Count - 1; 0 <= j; j--)
245 {
246 value = value.Insert(matches[j].Index, "!");
247 }
248 227
249 row[i] = value; 228 // escape things that look like wix variables
250 break; 229 var matches = Common.WixVariableRegex.Matches(value);
230 for (var j = matches.Count - 1; 0 <= j; j--)
231 {
232 value = value.Insert(matches[j].Index, "!");
251 } 233 }
252 } 234
235 row[i] = value;
236 break;
253 } 237 }
254 } 238 }
255 } 239 }
256
257 output.Tables.Add(table);
258 } 240 }
259 241
242 output.Tables.Add(table);
260 } 243 }
261 } 244 }
262 } 245 }
@@ -634,82 +617,82 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
634 { 617 {
635 switch (table.Name) 618 switch (table.Name)
636 { 619 {
637 case "WixFile": 620 case "WixFile":
638 case "MsiFileHash": 621 case "MsiFileHash":
639 ConnectTableToSection(table, fileSectionIdIndex, 0); 622 ConnectTableToSection(table, fileSectionIdIndex, 0);
640 break; 623 break;
641 case "MsiAssembly": 624 case "MsiAssembly":
642 case "MsiAssemblyName": 625 case "MsiAssemblyName":
643 ConnectTableToSection(table, componentSectionIdIndex, 0); 626 ConnectTableToSection(table, componentSectionIdIndex, 0);
644 break; 627 break;
645 case "MsiPackageCertificate": 628 case "MsiPackageCertificate":
646 case "MsiPatchCertificate": 629 case "MsiPatchCertificate":
647 ConnectTableToSection(table, digitalCertificateSectionIdIndex, 1); 630 ConnectTableToSection(table, digitalCertificateSectionIdIndex, 1);
648 break; 631 break;
649 case "CreateFolder": 632 case "CreateFolder":
650 case "FeatureComponents": 633 case "FeatureComponents":
651 case "MoveFile": 634 case "MoveFile":
652 case "ReserveCost": 635 case "ReserveCost":
653 case "ODBCTranslator": 636 case "ODBCTranslator":
654 ConnectTableToSection(table, componentSectionIdIndex, 1); 637 ConnectTableToSection(table, componentSectionIdIndex, 1);
655 break; 638 break;
656 case "TypeLib": 639 case "TypeLib":
657 ConnectTableToSection(table, componentSectionIdIndex, 2); 640 ConnectTableToSection(table, componentSectionIdIndex, 2);
658 break; 641 break;
659 case "Shortcut": 642 case "Shortcut":
660 case "Environment": 643 case "Environment":
661 ConnectTableToSection(table, componentSectionIdIndex, 3); 644 ConnectTableToSection(table, componentSectionIdIndex, 3);
662 break; 645 break;
663 case "RemoveRegistry": 646 case "RemoveRegistry":
664 ConnectTableToSection(table, componentSectionIdIndex, 4); 647 ConnectTableToSection(table, componentSectionIdIndex, 4);
665 break; 648 break;
666 case "ServiceControl": 649 case "ServiceControl":
667 ConnectTableToSection(table, componentSectionIdIndex, 5); 650 ConnectTableToSection(table, componentSectionIdIndex, 5);
668 break; 651 break;
669 case "IniFile": 652 case "IniFile":
670 case "RemoveIniFile": 653 case "RemoveIniFile":
671 ConnectTableToSection(table, componentSectionIdIndex, 7); 654 ConnectTableToSection(table, componentSectionIdIndex, 7);
672 break; 655 break;
673 case "AppId": 656 case "AppId":
674 ConnectTableToSection(table, appIdSectionIdIndex, 0); 657 ConnectTableToSection(table, appIdSectionIdIndex, 0);
675 break; 658 break;
676 case "Condition": 659 case "Condition":
677 ConnectTableToSection(table, featureSectionIdIndex, 0); 660 ConnectTableToSection(table, featureSectionIdIndex, 0);
678 break; 661 break;
679 case "ODBCSourceAttribute": 662 case "ODBCSourceAttribute":
680 ConnectTableToSection(table, odbcDataSourceSectionIdIndex, 0); 663 ConnectTableToSection(table, odbcDataSourceSectionIdIndex, 0);
681 break; 664 break;
682 case "ODBCAttribute": 665 case "ODBCAttribute":
683 ConnectTableToSection(table, odbcDriverSectionIdIndex, 0); 666 ConnectTableToSection(table, odbcDriverSectionIdIndex, 0);
684 break; 667 break;
685 case "AdminExecuteSequence": 668 case "AdminExecuteSequence":
686 case "AdminUISequence": 669 case "AdminUISequence":
687 case "AdvtExecuteSequence": 670 case "AdvtExecuteSequence":
688 case "AdvtUISequence": 671 case "AdvtUISequence":
689 case "InstallExecuteSequence": 672 case "InstallExecuteSequence":
690 case "InstallUISequence": 673 case "InstallUISequence":
691 ConnectTableToSection(table, customActionSectionIdIndex, 0); 674 ConnectTableToSection(table, customActionSectionIdIndex, 0);
692 break; 675 break;
693 case "LockPermissions": 676 case "LockPermissions":
694 case "MsiLockPermissions": 677 case "MsiLockPermissions":
695 foreach (var row in table.Rows) 678 foreach (var row in table.Rows)
696 {
697 var lockObject = (string)row[0];
698 var tableName = (string)row[1];
699 switch (tableName)
700 { 679 {
701 case "File": 680 var lockObject = (string)row[0];
702 row.SectionId = (string)fileSectionIdIndex[lockObject]; 681 var tableName = (string)row[1];
703 break; 682 switch (tableName)
704 case "Registry": 683 {
705 row.SectionId = (string)registrySectionIdIndex[lockObject]; 684 case "File":
706 break; 685 row.SectionId = (string)fileSectionIdIndex[lockObject];
707 case "ServiceInstall": 686 break;
708 row.SectionId = (string)serviceInstallSectionIdIndex[lockObject]; 687 case "Registry":
709 break; 688 row.SectionId = (string)registrySectionIdIndex[lockObject];
689 break;
690 case "ServiceInstall":
691 row.SectionId = (string)serviceInstallSectionIdIndex[lockObject];
692 break;
693 }
710 } 694 }
711 } 695 break;
712 break;
713 } 696 }
714 } 697 }
715 698