/*
* Copyright ( c ) 2020 , 2021 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation . Oracle designates this
* particular file as subject to the " Classpath " exception as provided
* by Oracle in the LICENSE file that accompanied this code .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
#ifndef MsiDb_h
#define MsiDb_h
#include <windows.h>
#include <msiquery.h>
#include "MsiUtils.h"
class Guid;
namespace msi {
void closeDatabaseView(MSIHANDLE h);
class CA;
class DatabaseView;
class DatabaseRecord;
/**
* Opens product ' s database to query properties .
* The database is opened in R / O mode , i . e . it is safe to call this method
* even if there is active install / uninstall session . Unlike MsiOpenProduct ( ) ,
* it never fails with 1618 ( ' Another installation is
* already in progress ' ) error code .
*
* Database can be opened from product code GUID , path to msi package or from
* custom action .
*
* If opened from CA the database is opened in R / W mode , however only adding
* new temporary records is supported . It is forbidden to change data in
* existing records .
*/
class Database {
public :
/**
* Opens msi database from the given product code GUID .
* Throws exception if fails .
*/
explicit Database(const Guid& productCode);
/**
* Opens msi database from the given path to . msi file .
* Throws exception if fails .
*/
explicit Database(const tstring& msiPath);
/**
* Opens msi database from the given custom action .
* Throws exception if fails .
*/
explicit Database(const CA& ca);
~Database() {
if (dbHandle != 0 ) {
closeMSIHANDLE(dbHandle);
}
}
/**
* Returns value of property with the given name .
* Throws NoMoreItemsError if property with the given name doesn ' t exist
* or Error if some error occurred .
*/
tstring getProperty(const tstring& name) const ;
/**
* Returns value of property with the given name .
* Returns empty string if property with the given name doesn ' t exist or
* if some error occurred .
*/
tstring getProperty(const std::nothrow_t&, const tstring& name) const ;
friend class DatabaseView;
private :
Database(const Database&);
Database& operator =(const Database&);
private :
const tstring msiPath;
MSIHANDLE dbHandle;
};
typedef std::unique_ptr<Database> DatabasePtr;
class DatabaseRecord {
public :
DatabaseRecord(): handle(MSIHANDLE(0 )) {
}
DatabaseRecord(const DatabaseRecord& other): handle(MSIHANDLE(0 )) {
handle = other.handle;
other.handle = 0 ;
}
DatabaseRecord& operator =(const DatabaseRecord& other);
friend class DatabaseView;
explicit DatabaseRecord(unsigned fieldCount);
explicit DatabaseRecord(DatabaseView& view) : handle(MSIHANDLE(0 )) {
fetch(view);
}
~DatabaseRecord() {
if (handle != 0 ) {
closeMSIHANDLE(handle);
}
}
DatabaseRecord& fetch(DatabaseView& view);
DatabaseRecord& tryFetch(DatabaseView& view);
DatabaseRecord& setString(unsigned idx, const tstring& v);
DatabaseRecord& setInteger(unsigned idx, int v);
DatabaseRecord& setStreamFromFile(unsigned idx, const tstring& v);
unsigned getFieldCount() const ;
tstring getString(unsigned idx) const ;
int getInteger(unsigned idx) const ;
void saveStreamToFile(unsigned idx, const tstring& path) const ;
bool empty() const {
return 0 == handle;
}
MSIHANDLE getHandle() const {
return handle;
}
private :
mutable MSIHANDLE handle;
};
class DatabaseView {
public :
DatabaseView(const Database& db, const tstring& sqlQuery,
const DatabaseRecord& queryParam=DatabaseRecord());
~DatabaseView() {
if (handle != 0 ) {
closeMSIHANDLE(handle);
}
}
DatabaseRecord fetch();
DatabaseRecord tryFetch();
DatabaseView& modify(const DatabaseRecord& record, MSIMODIFY mode);
private :
tstring sqlQuery;
const Database& db;
MSIHANDLE handle;
};
} // namespace msi
#endif // #ifndef MsiDb_h
Messung V0.5 in Prozent C=95 H=94 G=94
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland