aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolset.Dtf.WindowsInstaller/ColumnInfo.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dtf/WixToolset.Dtf.WindowsInstaller/ColumnInfo.cs')
-rw-r--r--src/dtf/WixToolset.Dtf.WindowsInstaller/ColumnInfo.cs297
1 files changed, 297 insertions, 0 deletions
diff --git a/src/dtf/WixToolset.Dtf.WindowsInstaller/ColumnInfo.cs b/src/dtf/WixToolset.Dtf.WindowsInstaller/ColumnInfo.cs
new file mode 100644
index 00000000..43363230
--- /dev/null
+++ b/src/dtf/WixToolset.Dtf.WindowsInstaller/ColumnInfo.cs
@@ -0,0 +1,297 @@
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.Dtf.WindowsInstaller
4{
5 using System;
6 using System.IO;
7 using System.Text;
8 using System.Globalization;
9 using System.Diagnostics.CodeAnalysis;
10
11 /// <summary>
12 /// Defines a single column of a table in an installer database.
13 /// </summary>
14 /// <remarks>Once created, a ColumnInfo object is immutable.</remarks>
15 public class ColumnInfo
16 {
17 private string name;
18 private Type type;
19 private int size;
20 private bool isRequired;
21 private bool isTemporary;
22 private bool isLocalizable;
23
24 /// <summary>
25 /// Creates a new ColumnInfo object from a column definition.
26 /// </summary>
27 /// <param name="name">name of the column</param>
28 /// <param name="columnDefinition">column definition string</param>
29 /// <seealso cref="ColumnDefinitionString"/>
30 public ColumnInfo(string name, string columnDefinition)
31 : this(name, typeof(String), 0, false, false, false)
32 {
33 if (name == null)
34 {
35 throw new ArgumentNullException("name");
36 }
37
38 if (columnDefinition == null)
39 {
40 throw new ArgumentNullException("columnDefinition");
41 }
42
43 switch (Char.ToLower(columnDefinition[0], CultureInfo.InvariantCulture))
44 {
45 case 'i': this.type = typeof(Int32);
46 break;
47 case 'j': this.type = typeof(Int32); this.isTemporary = true;
48 break;
49 case 'g': this.type = typeof(String); this.isTemporary = true;
50 break;
51 case 'l': this.type = typeof(String); this.isLocalizable = true;
52 break;
53 case 'o': this.type = typeof(Stream); this.isTemporary = true;
54 break;
55 case 's': this.type = typeof(String);
56 break;
57 case 'v': this.type = typeof(Stream);
58 break;
59 default: throw new InstallerException();
60 }
61
62 this.isRequired = Char.IsLower(columnDefinition[0]);
63 this.size = Int32.Parse(
64 columnDefinition.Substring(1),
65 CultureInfo.InvariantCulture.NumberFormat);
66 if (this.type == typeof(Int32) && this.size <= 2)
67 {
68 this.type = typeof(Int16);
69 }
70 }
71
72 /// <summary>
73 /// Creates a new ColumnInfo object from a list of parameters.
74 /// </summary>
75 /// <param name="name">name of the column</param>
76 /// <param name="type">type of the column; must be one of the following:
77 /// Int16, Int32, String, or Stream</param>
78 /// <param name="size">the maximum number of characters for String columns;
79 /// ignored for other column types</param>
80 /// <param name="isRequired">true if the column is required to have a non-null value</param>
81 public ColumnInfo(string name, Type type, int size, bool isRequired)
82 : this(name, type, size, isRequired, false, false)
83 {
84 }
85
86 /// <summary>
87 /// Creates a new ColumnInfo object from a list of parameters.
88 /// </summary>
89 /// <param name="name">name of the column</param>
90 /// <param name="type">type of the column; must be one of the following:
91 /// Int16, Int32, String, or Stream</param>
92 /// <param name="size">the maximum number of characters for String columns;
93 /// ignored for other column types</param>
94 /// <param name="isRequired">true if the column is required to have a non-null value</param>
95 /// <param name="isTemporary">true to if the column is only in-memory and
96 /// not persisted with the database</param>
97 /// <param name="isLocalizable">for String columns, indicates the column
98 /// is localizable; ignored for other column types</param>
99 public ColumnInfo(string name, Type type, int size, bool isRequired, bool isTemporary, bool isLocalizable)
100 {
101 if (name == null)
102 {
103 throw new ArgumentNullException("name");
104 }
105
106 if (type == typeof(Int32))
107 {
108 size = 4;
109 isLocalizable = false;
110 }
111 else if (type == typeof(Int16))
112 {
113 size = 2;
114 isLocalizable = false;
115 }
116 else if (type == typeof(String))
117 {
118 }
119 else if (type == typeof(Stream))
120 {
121 isLocalizable = false;
122 }
123 else
124 {
125 throw new ArgumentOutOfRangeException("type");
126 }
127
128 this.name = name;
129 this.type = type;
130 this.size = size;
131 this.isRequired = isRequired;
132 this.isTemporary = isTemporary;
133 this.isLocalizable = isLocalizable;
134 }
135
136 /// <summary>
137 /// Gets the name of the column.
138 /// </summary>
139 /// <value>name of the column</value>
140 public string Name
141 {
142 get { return this.name; }
143 }
144
145 /// <summary>
146 /// Gets the type of the column as a System.Type. This is one of the following: Int16, Int32, String, or Stream
147 /// </summary>
148 /// <value>type of the column</value>
149 [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")]
150 public Type Type
151 {
152 get { return this.type; }
153 }
154
155 /// <summary>
156 /// Gets the type of the column as an integer that can be cast to a System.Data.DbType. This is one of the following: Int16, Int32, String, or Binary
157 /// </summary>
158 /// <value>equivalent DbType of the column as an integer</value>
159 public int DBType
160 {
161 get
162 {
163 if (this.type == typeof(Int16)) return 10;
164 else if (this.type == typeof(Int32)) return 11;
165 else if (this.type == typeof(Stream)) return 1;
166 else return 16;
167 }
168 }
169
170 /// <summary>
171 /// Gets the size of the column.
172 /// </summary>
173 /// <value>The size of integer columns this is either 2 or 4. For string columns this is the maximum
174 /// recommended length of the string, or 0 for unlimited length. For stream columns, 0 is returned.</value>
175 public int Size
176 {
177 get { return this.size; }
178 }
179
180 /// <summary>
181 /// Gets a value indicating whether the column must be non-null when inserting a record.
182 /// </summary>
183 /// <value>required status of the column</value>
184 public bool IsRequired
185 {
186 get { return this.isRequired; }
187 }
188
189 /// <summary>
190 /// Gets a value indicating whether the column is temporary. Temporary columns are not persisted
191 /// when the database is saved to disk.
192 /// </summary>
193 /// <value>temporary status of the column</value>
194 public bool IsTemporary
195 {
196 get { return this.isTemporary; }
197 }
198
199 /// <summary>
200 /// Gets a value indicating whether the column is a string column that is localizable.
201 /// </summary>
202 /// <value>localizable status of the column</value>
203 public bool IsLocalizable
204 {
205 get { return this.isLocalizable; }
206 }
207
208 /// <summary>
209 /// Gets an SQL fragment that can be used to create this column within a CREATE TABLE statement.
210 /// </summary>
211 /// <value>SQL fragment to be used for creating the column</value>
212 /// <remarks><p>
213 /// Examples:
214 /// <list type="bullet">
215 /// <item>LONG</item>
216 /// <item>SHORT TEMPORARY</item>
217 /// <item>CHAR(0) LOCALIZABLE</item>
218 /// <item>CHAR(72) NOT NULL LOCALIZABLE</item>
219 /// <item>OBJECT</item>
220 /// </list>
221 /// </p></remarks>
222 public string SqlCreateString
223 {
224 get
225 {
226 StringBuilder s = new StringBuilder();
227 s.AppendFormat("`{0}` ", this.name);
228 if (this.type == typeof(Int16)) s.Append("SHORT");
229 else if (this.type == typeof(Int32)) s.Append("LONG");
230 else if (this.type == typeof(String)) s.AppendFormat("CHAR({0})", this.size);
231 else s.Append("OBJECT");
232 if (this.isRequired) s.Append(" NOT NULL");
233 if (this.isTemporary) s.Append(" TEMPORARY");
234 if (this.isLocalizable) s.Append(" LOCALIZABLE");
235 return s.ToString();
236 }
237 }
238
239 /// <summary>
240 /// Gets a short string defining the type and size of the column.
241 /// </summary>
242 /// <value>
243 /// The definition string consists
244 /// of a single letter representing the data type followed by the width of the column (in characters
245 /// when applicable, bytes otherwise). A width of zero designates an unbounded width (for example,
246 /// long text fields and streams). An uppercase letter indicates that null values are allowed in
247 /// the column.
248 /// </value>
249 /// <remarks><p>
250 /// <list>
251 /// <item>s? - String, variable length (?=1-255)</item>
252 /// <item>s0 - String, variable length</item>
253 /// <item>i2 - Short integer</item>
254 /// <item>i4 - Long integer</item>
255 /// <item>v0 - Binary Stream</item>
256 /// <item>g? - Temporary string (?=0-255)</item>
257 /// <item>j? - Temporary integer (?=0,1,2,4)</item>
258 /// <item>O0 - Temporary object (stream)</item>
259 /// <item>l? - Localizable string, variable length (?=1-255)</item>
260 /// <item>l0 - Localizable string, variable length</item>
261 /// </list>
262 /// </p></remarks>
263 public string ColumnDefinitionString
264 {
265 get
266 {
267 char t;
268 if (this.type == typeof(Int16) || this.type == typeof(Int32))
269 {
270 t = (this.isTemporary ? 'j' : 'i');
271 }
272 else if (this.type == typeof(String))
273 {
274 t = (this.isTemporary ? 'g' : this.isLocalizable ? 'l' : 's');
275 }
276 else
277 {
278 t = (this.isTemporary ? 'O' : 'v');
279 }
280 return String.Format(
281 CultureInfo.InvariantCulture,
282 "{0}{1}",
283 (this.isRequired ? t : Char.ToUpper(t, CultureInfo.InvariantCulture)),
284 this.size);
285 }
286 }
287
288 /// <summary>
289 /// Gets the name of the column.
290 /// </summary>
291 /// <returns>Name of the column.</returns>
292 public override string ToString()
293 {
294 return this.Name;
295 }
296 }
297}