aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolset.Dtf.WindowsInstaller.Linq/QDatabase.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dtf/WixToolset.Dtf.WindowsInstaller.Linq/QDatabase.cs214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/dtf/WixToolset.Dtf.WindowsInstaller.Linq/QDatabase.cs b/src/dtf/WixToolset.Dtf.WindowsInstaller.Linq/QDatabase.cs
new file mode 100644
index 00000000..b4de2f60
--- /dev/null
+++ b/src/dtf/WixToolset.Dtf.WindowsInstaller.Linq/QDatabase.cs
@@ -0,0 +1,214 @@
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.Linq
4{
5 using System;
6 using System.IO;
7 using WixToolset.Dtf.WindowsInstaller.Linq.Entities;
8
9 /// <summary>
10 /// Allows any Database instance to be converted into a queryable database.
11 /// </summary>
12 public static class Queryable
13 {
14 /// <summary>
15 /// Converts any Database instance into a queryable database.
16 /// </summary>
17 /// <param name="db"></param>
18 /// <returns>Queryable database instance that operates on the same
19 /// MSI handle.</returns>
20 /// <remarks>
21 /// This extension method is meant for convenient on-the-fly conversion.
22 /// If the existing database instance already happens to be a QDatabase,
23 /// then it is returned unchanged. Otherwise since the new database
24 /// carries the same MSI handle, only one of the instances needs to be
25 /// closed, not both.
26 /// </remarks>
27 public static QDatabase AsQueryable(this Database db)
28 {
29 QDatabase qdb = db as QDatabase;
30 if (qdb == null && db != null)
31 {
32 qdb = new QDatabase(db.Handle, true, db.FilePath, db.OpenMode);
33 }
34 return qdb;
35 }
36 }
37
38 /// <summary>
39 /// Queryable MSI database - extends the base Database class with
40 /// LINQ query functionality along with predefined entity types
41 /// for common tables.
42 /// </summary>
43 public class QDatabase : Database
44 {
45 /// <summary>
46 /// Opens an existing database in read-only mode.
47 /// </summary>
48 /// <param name="filePath">Path to the database file.</param>
49 /// <exception cref="InstallerException">the database could not be created/opened</exception>
50 /// <remarks>
51 /// Because this constructor initiates database access, it cannot be used with a
52 /// running installation.
53 /// <para>The Database object should be <see cref="InstallerHandle.Close"/>d after use.
54 /// The finalizer will close the handle if it is still open, however due to the nondeterministic
55 /// nature of finalization it is best that the handle be closed manually as soon as it is no
56 /// longer needed, as leaving lots of unused handles open can degrade performance.</para>
57 /// </remarks>
58 public QDatabase(string filePath)
59 : base(filePath)
60 {
61 }
62
63 /// <summary>
64 /// Opens an existing database with another database as output.
65 /// </summary>
66 /// <param name="filePath">Path to the database to be read.</param>
67 /// <param name="outputPath">Open mode for the database</param>
68 /// <returns>Database object representing the created or opened database</returns>
69 /// <exception cref="InstallerException">the database could not be created/opened</exception>
70 /// <remarks>
71 /// When a database is opened as the output of another database, the summary information stream
72 /// of the output database is actually a read-only mirror of the original database and thus cannot
73 /// be changed. Additionally, it is not persisted with the database. To create or modify the
74 /// summary information for the output database it must be closed and re-opened.
75 /// <para>The returned Database object should be <see cref="InstallerHandle.Close"/>d after use.
76 /// The finalizer will close the handle if it is still open, however due to the nondeterministic
77 /// nature of finalization it is best that the handle be closed manually as soon as it is no
78 /// longer needed, as leaving lots of unused handles open can degrade performance.</para>
79 /// </remarks>
80 public QDatabase(string filePath, string outputPath)
81 : base(filePath, outputPath)
82 {
83 }
84
85 /// <summary>
86 /// Opens an existing database or creates a new one.
87 /// </summary>
88 /// <param name="filePath">Path to the database file. If an empty string
89 /// is supplied, a temporary database is created that is not persisted.</param>
90 /// <param name="mode">Open mode for the database</param>
91 /// <exception cref="InstallerException">the database could not be created/opened</exception>
92 /// <remarks>
93 /// To make and save changes to a database first open the database in transaction,
94 /// create or, or direct mode. After making the changes, always call the Commit method
95 /// before closing the database handle. The Commit method flushes all buffers.
96 /// <para>Always call the Commit method on a database that has been opened in direct
97 /// mode before closing the database. Failure to do this may corrupt the database.</para>
98 /// <para>Because this constructor initiates database access, it cannot be used with a
99 /// running installation.</para>
100 /// <para>The Database object should be <see cref="InstallerHandle.Close"/>d after use.
101 /// The finalizer will close the handle if it is still open, however due to the nondeterministic
102 /// nature of finalization it is best that the handle be closed manually as soon as it is no
103 /// longer needed, as leaving lots of unused handles open can degrade performance.</para>
104 /// </remarks>
105 public QDatabase(string filePath, DatabaseOpenMode mode)
106 : base(filePath, mode)
107 {
108 }
109
110 /// <summary>
111 /// Creates a new database from an MSI handle.
112 /// </summary>
113 /// <param name="handle">Native MSI database handle.</param>
114 /// <param name="ownsHandle">True if the handle should be closed
115 /// when the database object is disposed</param>
116 /// <param name="filePath">Path of the database file, if known</param>
117 /// <param name="openMode">Mode the handle was originally opened in</param>
118 protected internal QDatabase(
119 IntPtr handle, bool ownsHandle, string filePath, DatabaseOpenMode openMode)
120 : base(handle, ownsHandle, filePath, openMode)
121 {
122 }
123
124 /// <summary>
125 /// Gets or sets a log where all MSI SQL queries are written.
126 /// </summary>
127 /// <remarks>
128 /// The log can be useful for debugging, or simply to watch the LINQ magic in action.
129 /// </remarks>
130 public TextWriter Log { get; set; }
131
132 /// <summary>
133 /// Gets a queryable table from the datbaase.
134 /// </summary>
135 /// <param name="table">name of the table</param>
136 public QTable<QRecord> this[string table]
137 {
138 get
139 {
140 return new QTable<QRecord>(this, table);
141 }
142 }
143
144 #if !CODE_ANALYSIS
145 #region Queryable tables
146
147 /// <summary>Queryable standard table with predefined specialized record type.</summary>
148 public QTable<Component_> Components
149 { get { return new QTable<Component_>(this); } }
150
151 /// <summary>Queryable standard table with predefined specialized record type.</summary>
152 public QTable<CreateFolder_> CreateFolders
153 { get { return new QTable<CreateFolder_>(this); } }
154
155 /// <summary>Queryable standard table with predefined specialized record type.</summary>
156 public QTable<CustomAction_> CustomActions
157 { get { return new QTable<CustomAction_>(this); } }
158
159 /// <summary>Queryable standard table with predefined specialized record type.</summary>
160 public QTable<Directory_> Directories
161 { get { return new QTable<Directory_>(this); } }
162
163 /// <summary>Queryable standard table with predefined specialized record type.</summary>
164 public QTable<DuplicateFile_> DuplicateFiles
165 { get { return new QTable<DuplicateFile_>(this); } }
166
167 /// <summary>Queryable standard table with predefined specialized record type.</summary>
168 public QTable<Feature_> Features
169 { get { return new QTable<Feature_>(this); } }
170
171 /// <summary>Queryable standard table with predefined specialized record type.</summary>
172 public QTable<FeatureComponent_> FeatureComponents
173 { get { return new QTable<FeatureComponent_>(this); } }
174
175 /// <summary>Queryable standard table with predefined specialized record type.</summary>
176 public QTable<File_> Files
177 { get { return new QTable<File_>(this); } }
178
179 /// <summary>Queryable standard table with predefined specialized record type.</summary>
180 public QTable<FileHash_> FileHashes
181 { get { return new QTable<FileHash_>(this); } }
182
183 /// <summary>Queryable standard table with predefined specialized record type.</summary>
184 public QTable<InstallSequence_> InstallExecuteSequences
185 { get { return new QTable<InstallSequence_>(this, "InstallExecuteSequence"); } }
186
187 /// <summary>Queryable standard table with predefined specialized record type.</summary>
188 public QTable<InstallSequence_> InstallUISequences
189 { get { return new QTable<InstallSequence_>(this, "InstallUISequence"); } }
190
191 /// <summary>Queryable standard table with predefined specialized record type.</summary>
192 public QTable<LaunchCondition_> LaunchConditions
193 { get { return new QTable<LaunchCondition_>(this); } }
194
195 /// <summary>Queryable standard table with predefined specialized record type.</summary>
196 public QTable<Media_> Medias
197 { get { return new QTable<Media_>(this); } }
198
199 /// <summary>Queryable standard table with predefined specialized record type.</summary>
200 public QTable<Property_> Properties
201 { get { return new QTable<Property_>(this); } }
202
203 /// <summary>Queryable standard table with predefined specialized record type.</summary>
204 public QTable<Registry_> Registries
205 { get { return new QTable<Registry_>(this); } }
206
207 /// <summary>Queryable standard table with predefined specialized record type.</summary>
208 public QTable<RemoveFile_> RemoveFiles
209 { get { return new QTable<RemoveFile_>(this); } }
210
211 #endregion // Queryable tables
212 #endif // !CODE_ANALYSIS
213 }
214}