OLD | NEW |
1 /** | 1 /** |
2 * \file database.h MSI database | 2 * \file database.h MSI database |
3 */ | 3 */ |
4 | 4 |
5 #ifndef DATABASE_H | 5 #ifndef DATABASE_H |
6 #define DATABASE_H | 6 #define DATABASE_H |
7 | 7 |
8 #include <string> | 8 #include <string> |
9 #include "windows.h" | 9 #include <memory> |
10 #include "msi.h" | 10 |
11 | 11 #include <Windows.h> |
| 12 #include <Msi.h> |
| 13 #include <MsiQuery.h> |
| 14 |
| 15 #include "installer-lib.h" |
| 16 #include "handle.h" |
12 #include "session.h" | 17 #include "session.h" |
13 | 18 |
14 /** | 19 // Forward declarations |
15 * A Windows Installer database as contained in an MSI file. | 20 class View ; |
16 * | 21 |
17 * The API for MSI databases is shared between installation and non-installation
contexts. | 22 //------------------------------------------------------- |
18 * Roughly speaking, outside an installation the database supports both read and
write, | 23 // Database |
19 * but inside an installation the database is read-only. | 24 //------------------------------------------------------- |
20 * The life cycle functions are not shared, in addition. | 25 /** |
21 * Outside of these restrictions, however, the API is mostly common. | 26 * A Windows Installer database as contained in an MSI file. |
22 * This class is the base class for the common API. | 27 * |
23 * Subclasses provide public constructors and provide access to API calls not in
common. | 28 * The API for MSI databases is shared between installation and non-installation
contexts. |
24 */ | 29 * Roughly speaking, outside an installation the database supports both read and
write, |
| 30 * but inside an installation the database is read-only. |
| 31 * The life cycle functions are not shared, in addition. |
| 32 * Outside of these restrictions, however, the API is mostly common. |
| 33 * This class is the base class for the common API. |
| 34 * Subclasses provide public constructors and provide access to API calls not in
common. |
| 35 */ |
25 class Database | 36 class Database |
26 { | 37 { |
27 protected: | 38 protected: |
28 /** | 39 typedef handle< MSIHANDLE, Disallow_Null, MSI_Generic_Destruction > handle_typ
e ; |
29 * Protected constructor. Life cycle depends strongly on context. | 40 |
30 */ | 41 /** |
31 Database( MSIHANDLE handle ); | 42 * Protected constructor. |
32 | 43 * |
33 /** | 44 * An MSI database handle is an overloaded type, used both for installation dat
abases and one opened outside an installation. |
34 * Destructor. | 45 * These database handles, while both databases, have different capabilities an
d are thus defined in subclasses. |
35 */ | 46 * Each subclass has the responsibility for obtaining a database handle appropr
iate to its circumstance. |
36 ~Database(); | 47 * |
37 | 48 * \sa MSDN "Obtaining a Database Handle" |
38 protected: | 49 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa370541(v=vs.85)
.aspx |
39 /** | 50 */ |
40 */ | 51 Database( MSIHANDLE handle ) |
41 MSIHANDLE handle; | 52 : handle( handle ) |
| 53 {} |
| 54 |
| 55 /** |
| 56 */ |
| 57 handle_type handle ; |
42 | 58 |
43 private: | 59 private: |
44 /** | 60 /** |
45 * Private copy constructor is declared but not defined. | 61 * Private copy constructor is declared but not defined. |
46 */ | 62 */ |
47 Database( const Database & ); | 63 Database( const Database & ) ; |
48 | 64 |
49 /** | 65 /** |
50 * Private assignment operator is declared but not defined. | 66 * Private assignment operator is declared but not defined. |
51 */ | 67 */ |
52 Database & operator=( const Database & ) ; | 68 Database & operator=( const Database & ) ; |
53 }; | 69 |
54 | 70 /** |
55 /** | 71 * Open a new view for this database. |
56 * A Windows Installer database in an installation context. | 72 * |
57 */ | 73 * \param query |
| 74 * An SQL query using the restricted MSI syntax |
| 75 * |
| 76 * \sa |
| 77 * - MSDN [MsiDatabaseOpenView function](http://msdn.microsoft.com/en-us/libr
ary/aa370082%28v=vs.85%29.aspx) |
| 78 */ |
| 79 msi_handle open_view( const wchar_t * query ) ; |
| 80 |
| 81 friend class View ; |
| 82 } ; |
| 83 |
| 84 /** |
| 85 * A Windows Installer database in an installation context. |
| 86 */ |
58 class Installation_Database : public Database | 87 class Installation_Database : public Database |
59 { | 88 { |
60 public: | 89 public: |
61 /** | 90 /** |
62 * The constructor of a database in an installation context has no arguments b
ecause the database is a part of that context. | 91 * The constructor of a database in an installation context has no arguments be
cause the database is a part of that context. |
63 */ | 92 */ |
64 Installation_Database( Immediate_Session & session ); | 93 Installation_Database( Immediate_Session & session ) ; |
65 }; | 94 } ; |
66 | 95 |
67 /** | 96 //------------------------------------------------------- |
68 * A Windows Installer database in a non-installation context. | 97 // |
69 */ | 98 //------------------------------------------------------- |
70 class Non_Installation_Database : public Database | 99 /** |
71 { | 100 * A Windows Installer database outside of an installation context, opened as a f
ile from the file system. |
72 }; | 101 * |
| 102 * This is a read-only version of a file-system database. |
| 103 * Refactor the class to obtain other open-modes. |
| 104 * |
| 105 */ |
| 106 class File_System_Database : public Database |
| 107 { |
| 108 /** |
| 109 * Open function is separate to enable initializing base class before construct
or body. |
| 110 * |
| 111 * \sa |
| 112 * - MSDN [MsiOpenDatabase function](http://msdn.microsoft.com/en-us/library/
aa370338%28v=vs.85%29.aspx) |
| 113 */ |
| 114 msi_handle handle_from_pathname( const wchar_t * pathname ) |
| 115 { |
| 116 MSIHANDLE handle ; |
| 117 UINT x = MsiOpenDatabaseW( pathname, MSIDBOPEN_READONLY, & handle ) ; |
| 118 if ( x != ERROR_SUCCESS ) |
| 119 { |
| 120 throw windows_api_error( "MsiOpenDatabaseW", x, "MSI database on file syst
em" ) ; |
| 121 } |
| 122 return msi_handle( handle ) ; |
| 123 } |
| 124 |
| 125 public: |
| 126 File_System_Database( const wchar_t * pathname ) |
| 127 : Database( handle_from_pathname( pathname ) ) |
| 128 {} |
| 129 } ; |
| 130 |
| 131 //------------------------------------------------------- |
| 132 // View |
| 133 //------------------------------------------------------- |
| 134 /* |
| 135 * The MSI database is accessible through a cut-down version of SQL. |
| 136 * There's no distinction between view and query in this dialect. |
| 137 * |
| 138 * \sa |
| 139 * - MSDN [Working with Queries](http://msdn.microsoft.com/en-us/library/aa3728
79%28v=vs.85%29.aspx) |
| 140 */ |
| 141 class View |
| 142 { |
| 143 /** |
| 144 * Policy class to close a view handle. |
| 145 * View handles don't get closed with the generic close function for other MSI
handles. |
| 146 */ |
| 147 template< class T > |
| 148 struct View_Destruction |
| 149 { |
| 150 /** |
| 151 * \sa MSDN [MsiViewClose function](http://msdn.microsoft.com/en-us/library/a
a370510%28v=vs.85%29.aspx) |
| 152 */ |
| 153 inline static void close( T handle ) |
| 154 { |
| 155 ::MsiViewClose( handle ) ; |
| 156 } |
| 157 } ; |
| 158 |
| 159 typedef handle< MSIHANDLE, Disallow_Null, View_Destruction > handle_type ; |
| 160 |
| 161 /** |
| 162 * Handle for the MSI view object |
| 163 */ |
| 164 handle_type _handle; |
| 165 |
| 166 public: |
| 167 /** |
| 168 * Ordinary constructor |
| 169 */ |
| 170 View( Database & db, wchar_t * query ) |
| 171 : _handle( db.open_view( query ) ) |
| 172 {} |
| 173 |
| 174 /** |
| 175 * Execute the query and return the first record in its results. |
| 176 * |
| 177 * \param arguments |
| 178 * List of parameters to supply as the query arguments (question marks). |
| 179 */ |
| 180 Record first( Record & arguments ) ; |
| 181 |
| 182 /** |
| 183 * Execute the query and return the first record in its results. |
| 184 * |
| 185 * With no arguments, this version of the function may only be used with a quer
y that takes no arguments. |
| 186 */ |
| 187 Record first() ; |
| 188 |
| 189 /** |
| 190 * Retrieve the next record. |
| 191 */ |
| 192 Record next() ; |
| 193 |
| 194 /** |
| 195 * End marker |
| 196 */ |
| 197 inline Record end() |
| 198 { |
| 199 return Record( Record::null_t() ) ; |
| 200 } |
| 201 } ; |
| 202 |
73 | 203 |
74 #endif | 204 #endif |
OLD | NEW |