Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: installer/src/installer-lib/database.h

Issue 5675960980471808: Updated installer with custom action (Closed)
Patch Set: Created March 8, 2014, 5:06 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: installer/src/installer-lib/database.h
===================================================================
--- a/installer/src/installer-lib/database.h
+++ b/installer/src/installer-lib/database.h
@@ -6,11 +6,21 @@
#define DATABASE_H
#include <string>
-#include "windows.h"
-#include "msi.h"
+#include <memory>
+#include <Windows.h>
+#include <Msi.h>
+#include <MsiQuery.h>
+
+#include "handle.h"
#include "session.h"
+// Forward declarations
+class View ;
+
+//-------------------------------------------------------
+// Database
+//-------------------------------------------------------
/**
* A Windows Installer database as contained in an MSI file.
*
@@ -25,32 +35,50 @@
class Database
{
protected:
- /**
- * Protected constructor. Life cycle depends strongly on context.
- */
- Database( MSIHANDLE handle );
+ typedef handle< MSIHANDLE, Disallow_Null, MSI_Generic_Destruction > handle_type ;
/**
- * Destructor.
+ * Protected constructor.
+ *
+ * An MSI database handle is an overloaded type, used both for installation databases and one opened outside an installation.
+ * These database handles, while both databases, have different capabilities and are thus defined in subclasses.
+ * Each subclass has the responsibility for obtaining a database handle appropriate to its circumstance.
+ *
+ * \sa MSDN "Obtaining a Database Handle"
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa370541(v=vs.85).aspx
*/
- ~Database();
+ Database( MSIHANDLE handle )
+ : handle( handle )
+ {}
-protected:
/**
*/
- MSIHANDLE handle;
+ handle_type handle ;
private:
/**
* Private copy constructor is declared but not defined.
*/
- Database( const Database & );
+ Database( const Database & ) ;
/**
* Private assignment operator is declared but not defined.
*/
Database & operator=( const Database & ) ;
-};
+
+ /**
+ * Open a new view for this database.
+ *
+ * \param query
+ * An SQL query using the restricted MSI syntax
+ *
+ * \sa
+ * - MSDN [MsiDatabaseOpenView function](http://msdn.microsoft.com/en-us/library/aa370082%28v=vs.85%29.aspx)
+ */
+ msi_handle open_view( const wchar_t * query ) ;
+
+ friend class View ;
+} ;
/**
* A Windows Installer database in an installation context.
@@ -61,14 +89,115 @@
/**
* The constructor of a database in an installation context has no arguments because the database is a part of that context.
*/
- Installation_Database( Immediate_Session & session );
-};
+ Installation_Database( Immediate_Session & session ) ;
+} ;
+//-------------------------------------------------------
+//
+//-------------------------------------------------------
/**
- * A Windows Installer database in a non-installation context.
+ * A Windows Installer database outside of an installation context, opened as a file from the file system.
+ *
+ * This is a read-only version of a file-system database.
+ * Refactor the class to obtain other open-modes.
+ *
*/
-class Non_Installation_Database : public Database
+class File_System_Database : public Database
{
-};
+ /**
+ * Open function is separate to enable initializing base class before constructor body.
+ *
+ * \sa
+ * - MSDN [MsiOpenDatabase function](http://msdn.microsoft.com/en-us/library/aa370338%28v=vs.85%29.aspx)
+ */
+ msi_handle handle_from_pathname( const wchar_t * pathname )
+ {
+ MSIHANDLE handle ;
+ UINT x = MsiOpenDatabaseW( pathname, MSIDBOPEN_READONLY, & handle ) ;
+ if ( x != ERROR_SUCCESS )
+ {
+ throw std::runtime_error( "Open database from file system failed" ) ;
+ }
+ return msi_handle( handle ) ;
+ }
+
+public:
+ File_System_Database( const wchar_t * pathname )
+ : Database( handle_from_pathname( pathname ) )
+ {}
+} ;
+
+//-------------------------------------------------------
+// View
+//-------------------------------------------------------
+/*
+ * The MSI database is accessible through a cut-down version of SQL.
+ * There's no distinction between view and query in this dialect.
+ *
+ * \sa
+ * - MSDN [Working with Queries](http://msdn.microsoft.com/en-us/library/aa372879%28v=vs.85%29.aspx)
+ */
+class View
+{
+ /**
+ * Policy class to close a view handle.
+ * View handles don't get closed with the generic close function for other MSI handles.
+ */
+ template< class T >
+ struct View_Destruction
+ {
+ /**
+ * \sa MSDN [MsiViewClose function](http://msdn.microsoft.com/en-us/library/aa370510%28v=vs.85%29.aspx)
+ */
+ inline static void close( T handle )
+ {
+ ::MsiViewClose( handle ) ;
+ }
+ } ;
+
+ typedef handle< MSIHANDLE, Disallow_Null, View_Destruction > handle_type ;
+
+ /**
+ * Handle for the MSI view object
+ */
+ handle_type _handle;
+
+public:
+ /**
+ * Ordinary constructor
+ */
+ View( Database & db, wchar_t * query )
+ : _handle( db.open_view( query ) )
+ {}
+
+ /**
+ * Execute the query and return the first record in its results.
+ *
+ * \param arguments
+ * List of parameters to supply as the query arguments (question marks).
+ */
+ Record first( Record & arguments ) ;
+
+ /**
+ * Execute the query and return the first record in its results.
+ *
+ * With no arguments, this version of the function may only be used with a query that takes no arguments.
+ */
+ Record first() ;
+
+ /**
+ * Retrieve the next record.
+ */
+ Record next() ;
+
+ /**
+ * End marker
+ */
+ inline Record end()
+ {
+ return Record( Record::null_t() ) ;
+ }
+} ;
+
#endif

Powered by Google App Engine
This is Rietveld