aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-12-07 14:19:05 -0800
committerRob Mensching <rob@firegiant.com>2017-12-07 14:19:05 -0800
commit49f1209035aac1fcfad5dbbe25f7b2306d3be86c (patch)
tree6ce5921493eb751b6d89c3faf0ebdf64110cbb65 /src/WixToolset.Data.WindowsInstaller/TableDefinition.cs
parentb1e662bd480241ea914f0f3d6bd174d9ffd03f5f (diff)
downloadwix-49f1209035aac1fcfad5dbbe25f7b2306d3be86c.tar.gz
wix-49f1209035aac1fcfad5dbbe25f7b2306d3be86c.tar.bz2
wix-49f1209035aac1fcfad5dbbe25f7b2306d3be86c.zip
Support MSI backends creating custom tables and remove WixToolset.Data.WindowsInstaller
Diffstat (limited to 'src/WixToolset.Data.WindowsInstaller/TableDefinition.cs')
-rw-r--r--src/WixToolset.Data.WindowsInstaller/TableDefinition.cs334
1 files changed, 0 insertions, 334 deletions
diff --git a/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs b/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs
deleted file mode 100644
index 40aaac84..00000000
--- a/src/WixToolset.Data.WindowsInstaller/TableDefinition.cs
+++ /dev/null
@@ -1,334 +0,0 @@
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.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Collections.ObjectModel;
8 using System.Text;
9 using System.Xml;
10
11 /// <summary>
12 /// Definition of a table in a database.
13 /// </summary>
14 public sealed class TableDefinition : IComparable<TableDefinition>
15 {
16 /// <summary>
17 /// Tracks the maximum number of columns supported in a real table.
18 /// This is a Windows Installer limitation.
19 /// </summary>
20 public const int MaxColumnsInRealTable = 32;
21
22 /// <summary>
23 /// Creates a table definition.
24 /// </summary>
25 /// <param name="name">Name of table to create.</param>
26 /// <param name="createSymbols">Flag if rows in this table create symbols.</param>
27 /// <param name="unreal">Flag if table is unreal.</param>
28 /// <param name="bootstrapperApplicationData">Flag if table is part of UX Manifest.</param>
29 public TableDefinition(string name, IList<ColumnDefinition> columns, bool createSymbols, bool unreal, bool bootstrapperApplicationData = false)
30 {
31 this.Name = name;
32 this.CreateSymbols = createSymbols;
33 this.Unreal = unreal;
34 this.BootstrapperApplicationData = bootstrapperApplicationData;
35
36 this.Columns = new ReadOnlyCollection<ColumnDefinition>(columns);
37 }
38
39 /// <summary>
40 /// Gets if rows in this table create symbols.
41 /// </summary>
42 /// <value>Flag if rows in this table create symbols.</value>
43 public bool CreateSymbols { get; private set; }
44
45 /// <summary>
46 /// Gets the name of the table.
47 /// </summary>
48 /// <value>Name of the table.</value>
49 public string Name { get; private set; }
50
51 /// <summary>
52 /// Gets if the table is unreal.
53 /// </summary>
54 /// <value>Flag if table is unreal.</value>
55 public bool Unreal { get; private set; }
56
57 /// <summary>
58 /// Gets if the table is a part of the bootstrapper application data manifest.
59 /// </summary>
60 /// <value>Flag if table is a part of the bootstrapper application data manifest.</value>
61 public bool BootstrapperApplicationData { get; private set; }
62
63 /// <summary>
64 /// Gets the collection of column definitions for this table.
65 /// </summary>
66 /// <value>Collection of column definitions for this table.</value>
67 public IList<ColumnDefinition> Columns { get; private set; }
68
69 /// <summary>
70 /// Gets the column definition in the table by index.
71 /// </summary>
72 /// <param name="columnIndex">Index of column to locate.</param>
73 /// <value>Column definition in the table by index.</value>
74 public ColumnDefinition this[int columnIndex]
75 {
76 get { return this.Columns[columnIndex]; }
77 }
78
79 /// <summary>
80 /// Gets the table definition in IDT format.
81 /// </summary>
82 /// <param name="keepAddedColumns">Whether to keep columns added in a transform.</param>
83 /// <returns>Table definition in IDT format.</returns>
84 public string ToIdtDefinition(bool keepAddedColumns)
85 {
86 bool first = true;
87 StringBuilder columnString = new StringBuilder();
88 StringBuilder dataString = new StringBuilder();
89 StringBuilder tableString = new StringBuilder();
90
91 tableString.Append(this.Name);
92 foreach (ColumnDefinition column in this.Columns)
93 {
94 // conditionally keep columns added in a transform; otherwise,
95 // break because columns can only be added at the end
96 if (column.Added && !keepAddedColumns)
97 {
98 break;
99 }
100
101 if (!first)
102 {
103 columnString.Append('\t');
104 dataString.Append('\t');
105 }
106
107 columnString.Append(column.Name);
108 dataString.Append(column.IdtType);
109
110 if (column.PrimaryKey)
111 {
112 tableString.AppendFormat("\t{0}", column.Name);
113 }
114
115 first = false;
116 }
117 columnString.Append("\r\n");
118 columnString.Append(dataString);
119 columnString.Append("\r\n");
120 columnString.Append(tableString);
121 columnString.Append("\r\n");
122
123 return columnString.ToString();
124 }
125
126 /// <summary>
127 /// Adds the validation rows to the _Validation table.
128 /// </summary>
129 /// <param name="validationTable">The _Validation table.</param>
130 public void AddValidationRows(Table validationTable)
131 {
132 foreach (ColumnDefinition columnDef in this.Columns)
133 {
134 Row row = validationTable.CreateRow(null);
135
136 row[0] = this.Name;
137
138 row[1] = columnDef.Name;
139
140 if (columnDef.Nullable)
141 {
142 row[2] = "Y";
143 }
144 else
145 {
146 row[2] = "N";
147 }
148
149 if (columnDef.IsMinValueSet)
150 {
151 row[3] = columnDef.MinValue;
152 }
153
154 if (columnDef.IsMaxValueSet)
155 {
156 row[4] = columnDef.MaxValue;
157 }
158
159 row[5] = columnDef.KeyTable;
160
161 if (columnDef.IsKeyColumnSet)
162 {
163 row[6] = columnDef.KeyColumn;
164 }
165
166 if (ColumnCategory.Unknown != columnDef.Category)
167 {
168 row[7] = columnDef.Category.ToString();
169 }
170
171 row[8] = columnDef.Possibilities;
172
173 row[9] = columnDef.Description;
174 }
175 }
176
177 /// <summary>
178 /// Compares this table definition to another table definition.
179 /// </summary>
180 /// <remarks>
181 /// Only Windows Installer traits are compared, allowing for updates to WiX-specific table definitions.
182 /// </remarks>
183 /// <param name="updated">The updated <see cref="TableDefinition"/> to compare with this target definition.</param>
184 /// <returns>0 if the tables' core properties are the same; otherwise, non-0.</returns>
185 public int CompareTo(TableDefinition updated)
186 {
187 // by definition, this object is greater than null
188 if (null == updated)
189 {
190 return 1;
191 }
192
193 // compare the table names
194 int ret = String.Compare(this.Name, updated.Name, StringComparison.Ordinal);
195
196 // compare the column count
197 if (0 == ret)
198 {
199 // transforms can only add columns
200 ret = Math.Min(0, updated.Columns.Count - this.Columns.Count);
201
202 // compare name, type, and length of each column
203 for (int i = 0; 0 == ret && this.Columns.Count > i; i++)
204 {
205 ColumnDefinition thisColumnDef = this.Columns[i];
206 ColumnDefinition updatedColumnDef = updated.Columns[i];
207
208 ret = thisColumnDef.CompareTo(updatedColumnDef);
209 }
210 }
211
212 return ret;
213 }
214
215 /// <summary>
216 /// Parses table definition from xml reader.
217 /// </summary>
218 /// <param name="reader">Reader to get data from.</param>
219 /// <returns>The TableDefintion represented by the Xml.</returns>
220 internal static TableDefinition Read(XmlReader reader)
221 {
222 bool empty = reader.IsEmptyElement;
223 bool createSymbols = false;
224 string name = null;
225 bool unreal = false;
226 bool bootstrapperApplicationData = false;
227
228 while (reader.MoveToNextAttribute())
229 {
230 switch (reader.LocalName)
231 {
232 case "createSymbols":
233 createSymbols = reader.Value.Equals("yes");
234 break;
235 case "name":
236 name = reader.Value;
237 break;
238 case "unreal":
239 unreal = reader.Value.Equals("yes");
240 break;
241 case "bootstrapperApplicationData":
242 bootstrapperApplicationData = reader.Value.Equals("yes");
243 break;
244 }
245 }
246
247 if (null == name)
248 {
249 throw new XmlException();
250 }
251
252 List<ColumnDefinition> columns = new List<ColumnDefinition>();
253 bool hasPrimaryKeyColumn = false;
254
255 // parse the child elements
256 if (!empty)
257 {
258 bool done = false;
259
260 while (!done && reader.Read())
261 {
262 switch (reader.NodeType)
263 {
264 case XmlNodeType.Element:
265 switch (reader.LocalName)
266 {
267 case "columnDefinition":
268 ColumnDefinition columnDefinition = ColumnDefinition.Read(reader);
269 columns.Add(columnDefinition);
270
271 if (columnDefinition.PrimaryKey)
272 {
273 hasPrimaryKeyColumn = true;
274 }
275 break;
276 default:
277 throw new XmlException();
278 }
279 break;
280 case XmlNodeType.EndElement:
281 done = true;
282 break;
283 }
284 }
285
286 if (!unreal && !bootstrapperApplicationData && !hasPrimaryKeyColumn)
287 {
288 throw new WixException(WixDataErrors.RealTableMissingPrimaryKeyColumn(SourceLineNumber.CreateFromUri(reader.BaseURI), name));
289 }
290
291 if (!done)
292 {
293 throw new XmlException();
294 }
295 }
296
297 TableDefinition tableDefinition = new TableDefinition(name, columns, createSymbols, unreal, bootstrapperApplicationData);
298 return tableDefinition;
299 }
300
301 /// <summary>
302 /// Persists an output in an XML format.
303 /// </summary>
304 /// <param name="writer">XmlWriter where the Output should persist itself as XML.</param>
305 internal void Write(XmlWriter writer)
306 {
307 writer.WriteStartElement("tableDefinition", TableDefinitionCollection.XmlNamespaceUri);
308
309 writer.WriteAttributeString("name", this.Name);
310
311 if (this.CreateSymbols)
312 {
313 writer.WriteAttributeString("createSymbols", "yes");
314 }
315
316 if (this.Unreal)
317 {
318 writer.WriteAttributeString("unreal", "yes");
319 }
320
321 if (this.BootstrapperApplicationData)
322 {
323 writer.WriteAttributeString("bootstrapperApplicationData", "yes");
324 }
325
326 foreach (ColumnDefinition columnDefinition in this.Columns)
327 {
328 columnDefinition.Write(writer);
329 }
330
331 writer.WriteEndElement();
332 }
333 }
334}