aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2017-10-14 16:12:07 -0700
committerRob Mensching <rob@firegiant.com>2017-10-14 16:12:07 -0700
commitdbde9e7104b907bbbaea17e21247d8cafc8b3a4c (patch)
tree0f5fbbb6fe12c6b2e5e622a0e18ce4c5b4eb2b96 /src/WixToolset.Core.WindowsInstaller/Msi/View.cs
parentfbf986eb97f68396797a89fc7d40dec07b775440 (diff)
downloadwix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.tar.gz
wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.tar.bz2
wix-dbde9e7104b907bbbaea17e21247d8cafc8b3a4c.zip
Massive refactoring to introduce the concept of IBackend
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Msi/View.cs')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Msi/View.cs189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Msi/View.cs b/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
new file mode 100644
index 00000000..d6542824
--- /dev/null
+++ b/src/WixToolset.Core.WindowsInstaller/Msi/View.cs
@@ -0,0 +1,189 @@
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.Msi
4{
5 using System;
6 using System.ComponentModel;
7 using System.Globalization;
8 using WixToolset.Core.Native;
9
10 /// <summary>
11 /// Enumeration of different modify modes.
12 /// </summary>
13 public enum ModifyView
14 {
15 /// <summary>
16 /// Writes current data in the cursor to a table row. Updates record if the primary
17 /// keys match an existing row and inserts if they do not match. Fails with a read-only
18 /// database. This mode cannot be used with a view containing joins.
19 /// </summary>
20 Assign = MsiInterop.MSIMODIFYASSIGN,
21
22 /// <summary>
23 /// Remove a row from the table. You must first call the Fetch function with the same
24 /// record. Fails if the row has been deleted. Works only with read-write records. This
25 /// mode cannot be used with a view containing joins.
26 /// </summary>
27 Delete = MsiInterop.MSIMODIFYDELETE,
28
29 /// <summary>
30 /// Inserts a record. Fails if a row with the same primary keys exists. Fails with a read-only
31 /// database. This mode cannot be used with a view containing joins.
32 /// </summary>
33 Insert = MsiInterop.MSIMODIFYINSERT,
34
35 /// <summary>
36 /// Inserts a temporary record. The information is not persistent. Fails if a row with the
37 /// same primary key exists. Works only with read-write records. This mode cannot be
38 /// used with a view containing joins.
39 /// </summary>
40 InsertTemporary = MsiInterop.MSIMODIFYINSERTTEMPORARY,
41
42 /// <summary>
43 /// Inserts or validates a record in a table. Inserts if primary keys do not match any row
44 /// and validates if there is a match. Fails if the record does not match the data in
45 /// the table. Fails if there is a record with a duplicate key that is not identical.
46 /// Works only with read-write records. This mode cannot be used with a view containing joins.
47 /// </summary>
48 Merge = MsiInterop.MSIMODIFYMERGE,
49
50 /// <summary>
51 /// Refreshes the information in the record. Must first call Fetch with the
52 /// same record. Fails for a deleted row. Works with read-write and read-only records.
53 /// </summary>
54 Refresh = MsiInterop.MSIMODIFYREFRESH,
55
56 /// <summary>
57 /// Updates or deletes and inserts a record into a table. Must first call Fetch with
58 /// the same record. Updates record if the primary keys are unchanged. Deletes old row and
59 /// inserts new if primary keys have changed. Fails with a read-only database. This mode cannot
60 /// be used with a view containing joins.
61 /// </summary>
62 Replace = MsiInterop.MSIMODIFYREPLACE,
63
64 /// <summary>
65 /// Refreshes the information in the supplied record without changing the position in the
66 /// result set and without affecting subsequent fetch operations. The record may then
67 /// be used for subsequent Update, Delete, and Refresh. All primary key columns of the
68 /// table must be in the query and the record must have at least as many fields as the
69 /// query. Seek cannot be used with multi-table queries. This mode cannot be used with
70 /// a view containing joins. See also the remarks.
71 /// </summary>
72 Seek = MsiInterop.MSIMODIFYSEEK,
73
74 /// <summary>
75 /// Updates an existing record. Non-primary keys only. Must first call Fetch. Fails with a
76 /// deleted record. Works only with read-write records.
77 /// </summary>
78 Update = MsiInterop.MSIMODIFYUPDATE
79 }
80
81 /// <summary>
82 /// Wrapper class for MSI API views.
83 /// </summary>
84 internal sealed class View : MsiHandle
85 {
86 /// <summary>
87 /// Constructor that creates a view given a database handle and a query.
88 /// </summary>
89 /// <param name="db">Handle to the database to run the query on.</param>
90 /// <param name="query">Query to be executed.</param>
91 public View(Database db, string query)
92 {
93 if (null == db)
94 {
95 throw new ArgumentNullException("db");
96 }
97
98 if (null == query)
99 {
100 throw new ArgumentNullException("query");
101 }
102
103 uint handle = 0;
104
105 int error = MsiInterop.MsiDatabaseOpenView(db.Handle, query, out handle);
106 if (0 != error)
107 {
108 throw new MsiException(error);
109 }
110
111 this.Handle = handle;
112 }
113
114 /// <summary>
115 /// Executes a view with no customizable parameters.
116 /// </summary>
117 public void Execute()
118 {
119 this.Execute(null);
120 }
121
122 /// <summary>
123 /// Executes a query substituing the values from the records into the customizable parameters
124 /// in the view.
125 /// </summary>
126 /// <param name="record">Record containing parameters to be substituded into the view.</param>
127 public void Execute(Record record)
128 {
129 int error = MsiInterop.MsiViewExecute(this.Handle, null == record ? 0 : record.Handle);
130 if (0 != error)
131 {
132 throw new MsiException(error);
133 }
134 }
135
136 /// <summary>
137 /// Fetches the next row in the view.
138 /// </summary>
139 /// <returns>Returns the fetched record; otherwise null.</returns>
140 public Record Fetch()
141 {
142 uint recordHandle;
143
144 int error = MsiInterop.MsiViewFetch(this.Handle, out recordHandle);
145 if (259 == error)
146 {
147 return null;
148 }
149 else if (0 != error)
150 {
151 throw new MsiException(error);
152 }
153
154 return new Record(recordHandle);
155 }
156
157 /// <summary>
158 /// Updates a fetched record.
159 /// </summary>
160 /// <param name="type">Type of modification mode.</param>
161 /// <param name="record">Record to be modified.</param>
162 public void Modify(ModifyView type, Record record)
163 {
164 int error = MsiInterop.MsiViewModify(this.Handle, Convert.ToInt32(type, CultureInfo.InvariantCulture), record.Handle);
165 if (0 != error)
166 {
167 throw new MsiException(error);
168 }
169 }
170
171 /// <summary>
172 /// Returns a record containing column names or definitions.
173 /// </summary>
174 /// <param name="columnType">Specifies a flag indicating what type of information is needed. Either MSICOLINFO_NAMES or MSICOLINFO_TYPES.</param>
175 /// <returns>The record containing information about the column.</returns>
176 public Record GetColumnInfo(int columnType)
177 {
178 uint recordHandle;
179
180 int error = MsiInterop.MsiViewGetColumnInfo(this.Handle, columnType, out recordHandle);
181 if (0 != error)
182 {
183 throw new MsiException(error);
184 }
185
186 return new Record(recordHandle);
187 }
188 }
189}