diff options
| author | Rob Mensching <rob@firegiant.com> | 2020-01-13 09:10:13 -0800 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2020-01-13 14:19:45 -0800 |
| commit | 94b941ee95a294228516097c269e27dfa41593ab (patch) | |
| tree | 208cb36a5a6a3e17f5d458cfaa679d6ca1a76e15 /src/WixToolset.Core.WindowsInstaller/Unbind | |
| parent | a2b1235d9c0dfba48b1badac428d89d1137da698 (diff) | |
| download | wix-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.cs | 325 |
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 | ||
