/****************************************************************************** Copyright (c) 2000 Microsoft Corporation Module Name: Abstract: This file contains the declaration of the interface to Jet Blue. Revision History: Davide Massarenti (Dmassare) 05/16/2000 created ******************************************************************************/ #if !defined(__INCLUDED___HCP___JETBLUELIB_H___) #define __INCLUDED___HCP___JETBLUELIB_H___ #include // // From HelpServiceTypeLib.idl // #include #include #include #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////// // // Values are 32 bit values layed out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---+-+-+-----------------------+-------------------------------+ // |Sev|C|R| Facility | Code | // +---+-+-+-----------------------+-------------------------------+ // // where // // Sev - is the severity code // // 00 - Success // 01 - Informational // 10 - Warning // 11 - Error // // C - is the Customer code flag // // R - is a reserved bit // // Facility - is the facility code // // Code - is the facility's status code // #define HRESULT_BASE_JET 0xA2000000 // C=1, Facility=0x200 //////////////////////////////////////////////////////////////////////////////// #define __MPC_EXIT_IF_JET_FAILS(hr,x) __MPC_EXIT_IF_METHOD_FAILS(hr,JetBlue::JetERRToHRESULT(x)) #define __MPC_JET__MTSAFE(sesid,err,x) \ { \ err = ::JetSetSessionContext( sesid, 0xDEAD ); \ \ if(err == JET_errSuccess) err = (x); \ \ ::JetResetSessionContext( sesid ); \ } #define __MPC_JET__MTSAFE_NORESULT(sesid,x) \ { \ JET_ERR err; \ \ __MPC_JET__MTSAFE(sesid,err,x); \ } #define __MPC_EXIT_IF_JET_FAILS__MTSAFE(sesid,hr,x) \ { \ JET_ERR err; \ \ __MPC_JET__MTSAFE(sesid,err,x); \ \ __MPC_EXIT_IF_JET_FAILS(hr,err); \ } #define __MPC_JET_CHECKHANDLE(hr,x,v) { if(x == v) __MPC_SET_ERROR_AND_EXIT(hr, E_HANDLE); } //////////////////////////////////////////////////////////////////////////////// #define __MPC_JET_INIT_RETRIEVE_COL(rc,pos,colid,pvdata,cbdata) \ rc[pos].columnid = colid;\ rc[pos].pvData = pvdata;\ rc[pos].cbData = cbdata;\ rc[pos].itagSequence = 1; #define __MPC_JET_COLUMNCREATE(name,type,max,grbit) \ { \ sizeof(JET_COLUMNCREATE), /* unsigned long cbStruct; # size of this structure (for future expansion) */ \ name , /* char *szColumnName; # column name */ \ type , /* JET_COLTYP coltyp; # column type */ \ max , /* unsigned long cbMax; # the maximum length of this column (only relevant for binary and text columns) */ \ grbit , /* JET_GRBIT grbit; # column options */ \ NULL , /* void *pvDefault # default value (NULL if none) */ \ 0 , /* unsigned long cbDefault; # length of default value */ \ 0 , /* unsigned long cp; # code page (for text columns only) */ \ 0 , /* JET_COLUMNID columnid; # returned column id */ \ JET_errSuccess /* JET_ERR err; # returned error code */ \ } #define __MPC_JET_COLUMNCREATE_ANSI(name,type,max,grbit) \ { \ sizeof(JET_COLUMNCREATE), /* unsigned long cbStruct; # size of this structure (for future expansion) */ \ name , /* char *szColumnName; # column name */ \ type , /* JET_COLTYP coltyp; # column type */ \ max , /* unsigned long cbMax; # the maximum length of this column (only relevant for binary and text columns) */ \ grbit , /* JET_GRBIT grbit; # column options */ \ NULL , /* void *pvDefault # default value (NULL if none) */ \ 0 , /* unsigned long cbDefault; # length of default value */ \ 1252 , /* unsigned long cp; # code page (for text columns only) */ \ 0 , /* JET_COLUMNID columnid; # returned column id */ \ JET_errSuccess /* JET_ERR err; # returned error code */ \ } #define __MPC_JET_COLUMNCREATE_UNICODE(name,type,max,grbit) \ { \ sizeof(JET_COLUMNCREATE), /* unsigned long cbStruct; # size of this structure (for future expansion) */ \ name , /* char *szColumnName; # column name */ \ type , /* JET_COLTYP coltyp; # column type */ \ max , /* unsigned long cbMax; # the maximum length of this column (only relevant for binary and text columns) */ \ grbit , /* JET_GRBIT grbit; # column options */ \ NULL , /* void *pvDefault # default value (NULL if none) */ \ 0 , /* unsigned long cbDefault; # length of default value */ \ 1200 , /* unsigned long cp; # code page (for text columns only) */ \ 0 , /* JET_COLUMNID columnid; # returned column id */ \ JET_errSuccess /* JET_ERR err; # returned error code */ \ } #define __MPC_JET_INDEXCREATE(name,keys,grbit,density) \ { \ sizeof(JET_INDEXCREATE), /* unsigned long cbStruct; # size of this structure (for future expansion) */ \ name , /* char *szIndexName; # index name */ \ (LPSTR)keys , /* char *szKey; # index key */ \ sizeof(keys) , /* unsigned long cbKey; # length of key */ \ grbit , /* JET_GRBIT grbit; # index options */ \ density /* unsigned long ulDensity; # index density */ \ /* # */ \ /* union # */ \ /* { # */ \ /* ULONG_PTR lcid; # lcid for the index (if JET_bitIndexUnicode NOT specified) */ \ /* JET_UNICODEINDEX *pidxunicode; # pointer to JET_UNICODEINDEX struct (if JET_bitIndexUnicode specified) */ \ /* }; # */ \ /* # */ \ /* unsigned long cbVarSegMac; # maximum length of variable length columns in index key */ \ /* JET_CONDITIONALCOLUMN *rgconditionalcolumn; # pointer to conditional column structure */ \ /* unsigned long cConditionalColumn; # number of conditional columns */ \ /* JET_ERR err; # returned error code */ \ } #define __MPC_JET_TABLECREATE(name,pages,density,cols,idxs) \ { \ sizeof(JET_TABLECREATE), /* unsigned long cbStruct; # size of this structure (for future expansion) */ \ name , /* char *szTableName; # name of table to create. */ \ NULL , /* char *szTemplateTableName; # name of table from which to inherit base DDL */ \ pages , /* unsigned long ulPages; # initial pages to allocate for table. */ \ density , /* unsigned long ulDensity; # table density. */ \ (JET_COLUMNCREATE*)cols, /* JET_COLUMNCREATE *rgcolumncreate; # array of column creation info */ \ ARRAYSIZE(cols) , /* unsigned long cColumns; # number of columns to create */ \ (JET_INDEXCREATE*)idxs , /* JET_INDEXCREATE *rgindexcreate; # array of index creation info */ \ ARRAYSIZE(idxs) , /* unsigned long cIndexes; # number of indexes to create */ \ 0 , /* JET_GRBIT grbit; # */ \ JET_tableidNil , /* JET_TABLEID tableid; # returned tableid. */ \ 0 , /* unsigned long cCreated; # count of objects created (columns+table+indexes). */ \ } //////////////////////////////////////////////////////////////////////////////// #define __MPC_JET_SETCTX(obj,ctx) { if(obj) { JET_SESID sesid = obj->GetSESID(); if(sesid != JET_sesidNil) ::JetSetSessionContext ( sesid, ctx ); } } #define __MPC_JET_RESETCTX(obj) { if(obj) { JET_SESID sesid = obj->GetSESID(); if(sesid != JET_sesidNil) ::JetResetSessionContext( sesid ); } } //////////////////////////////////////////////////////////////////////////////// namespace JetBlue { inline HRESULT JetERRToHRESULT( /*[in]*/ JET_ERR err ) { return (err < JET_errSuccess ? 0xA2000000 : 0) | (err & 0xFFFF); } //////////////////////////////////////// class Column; class Index; class Table; class Cursor; class Database; class Session; class SessionHandle; class SessionPool; typedef std::vector ColumnVector; typedef ColumnVector::iterator ColumnIter; typedef ColumnVector::const_iterator ColumnIterConst; typedef std::vector IndexVector; typedef IndexVector::iterator IndexIter; typedef IndexVector::const_iterator IndexIterConst; typedef std::map TableMap; typedef TableMap::iterator TableIter; typedef TableMap::const_iterator TableIterConst; typedef std::map DbMap; typedef DbMap::iterator DbIter; typedef DbMap::const_iterator DbIterConst; typedef std::map Id2Node; typedef Id2Node::iterator Id2NodeIter; typedef Id2Node::const_iterator Id2NodeIterConst; typedef std::map Node2Id; typedef Node2Id::iterator Node2IdIter; typedef Node2Id::const_iterator Node2IdIterConst; //////////////////////////////////////// class ColumnDefinition; class IndexDefinition; class TableDefinition; //////////////////////////////////////// class Column { friend class ColumnDefinition; friend class IndexDefinition; friend class TableDefinition; friend class Table; friend class Index; //////////////////////////////////////// JET_SESID m_sesid; JET_TABLEID m_tableid; MPC::string m_strName; JET_COLUMNDEF m_coldef; public: Column(); ~Column(); operator const MPC::string& () const { return m_strName; } operator const JET_COLUMNDEF&() const { return m_coldef ; } JET_SESID GetSESID () const { return m_sesid; } JET_TABLEID GetTABLEID () const { return m_tableid; } JET_COLUMNID GetCOLUMNID() const { return m_coldef.columnid; } //////////////////// HRESULT Get( /*[out]*/ CComVariant& vValue ); HRESULT Get( /*[out]*/ MPC::CComHGLOBAL& hgValue ); HRESULT Get( /*[out]*/ MPC::wstring& strValue ); HRESULT Get( /*[out]*/ MPC::string& strValue ); HRESULT Get( /*[out]*/ long& lValue ); HRESULT Get( /*[out]*/ short& sValue ); HRESULT Get( /*[out]*/ BYTE& bValue ); HRESULT Put( /*[in]*/ const VARIANT& vValue, /*[in]*/ int iIdxPos = -1 ); HRESULT Put( /*[in]*/ const MPC::CComHGLOBAL& hgValue ); HRESULT Put( /*[in]*/ const MPC::wstring& strValue ); HRESULT Put( /*[in]*/ const MPC::string& strValue ); HRESULT Put( /*[in]*/ LPCWSTR szValue ); HRESULT Put( /*[in]*/ LPCSTR szValue ); HRESULT Put( /*[in]*/ long lValue ); HRESULT Put( /*[in]*/ short sValue ); HRESULT Put( /*[in]*/ BYTE bValue ); }; class Index { friend class IndexDefinition; friend class TableDefinition; friend class Table; //////////////////////////////////////// JET_SESID m_sesid; JET_TABLEID m_tableid; MPC::string m_strName; JET_GRBIT m_grbitIndex; LONG m_cKey; LONG m_cEntry; LONG m_cPage; ColumnVector m_vecColumns; Column m_fake; // In case the Idx passed to the operator[] is wrong... //////////////////// HRESULT GenerateKey( /*[out]*/ LPSTR& szKey, /*[out]*/ unsigned long& cKey ); public: Index(); ~Index(); operator const MPC::string&() const { return m_strName; } JET_SESID GetSESID () const { return m_sesid; } JET_TABLEID GetTABLEID() const { return m_tableid; } //////////////////////////////////////// size_t NumOfColumns() { return m_vecColumns.size(); } int GetColPosition( LPCSTR szIdx ); Column& GetCol ( LPCSTR szIdx ); Column& GetCol ( int iIdx ); }; //////////////////////////////////////////////////////////////////////////////// class Table { friend class TableDefinition; friend class Cursor; //////////////////////////////////////// JET_SESID m_sesid; JET_DBID m_dbid; JET_TABLEID m_tableid; MPC::string m_strName; ColumnVector m_vecColumns; IndexVector m_vecIndexes; Index* m_idxSelected; Column m_fakeCol; // In case the argument passed to GetCol() is out-of-bound... Index m_fakeIdx; // In case the argument passed to GetIdx() is out-of-bound... //////////////////////////////////////// // // Methods used to create a cursor on a table. // Table(); HRESULT Duplicate( /*[in]*/ Table& tbl ); // //////////////////////////////////////// private: // Disable copy constructors... Table ( /*[in]*/ const Table& ); Table& operator=( /*[in]*/ const Table& ); public: Table( /*[in]*/ JET_SESID sesid, /*[in]*/ JET_DBID dbid, /*[in]*/ LPCSTR szName ); ~Table(); operator const MPC::string&() const { return m_strName; } JET_SESID GetSESID () const { return m_sesid; } JET_DBID GetDBID () const { return m_dbid; } JET_TABLEID GetTABLEID() const { return m_tableid; } //////////////////// HRESULT Refresh ( ); HRESULT Close ( /*[in]*/ bool fForce = false ); //////////////////// HRESULT Attach( /*[in]*/ JET_TABLEID tableid ); HRESULT Open ( ); HRESULT Create( ); HRESULT Create( /*[in]*/ JET_TABLECREATE* pDef ); HRESULT Delete( /*[in]*/ bool fForce = false ); //////////////////// HRESULT DupCursor( /*[in/out]*/ Cursor& cur ); HRESULT SelectIndex ( /*[in]*/ LPCSTR szIndex, /*[in]*/ JET_GRBIT grbit = JET_bitNoMove ); HRESULT SetIndexRange( /*[in]*/ JET_GRBIT grbit = JET_bitRangeRemove ); HRESULT PrepareInsert(); HRESULT PrepareUpdate(); HRESULT CancelChange (); HRESULT Move( /*[in]*/ JET_GRBIT grbit, /*[in]*/ long cRow , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek( /*[in]*/ JET_GRBIT grbit, /*[in]*/ VARIANT* rgKeys, /*[in]*/ int dwLen, /*[in]*/ bool *pfFound = NULL ); template HRESULT Seek( /*[in]*/ JET_GRBIT grbit, /*[in]*/ T value ) { CComVariant v( value ); return Seek( grbit, &v, 1 ); } HRESULT Get( /*[in]*/ int iArg, /*[out]*/ CComVariant* rgArg ); HRESULT Put( /*[in]*/ int iArg, /*[in] */ const CComVariant* rgArg ); HRESULT UpdateRecord( /*[in]*/ bool fMove = false ); HRESULT DeleteRecord( ); //////////////////////////////////////// size_t NumOfColumns() { return m_vecColumns.size(); } int GetColPosition( LPCSTR szIdx ); Column& GetCol ( LPCSTR szIdx ); Column& GetCol ( int iIdx ); //////////////////////////////////////// size_t NumOfIndexes() { return m_vecIndexes.size(); } int GetIdxPosition( LPCSTR szCol ); Index& GetIdx ( LPCSTR szCol ); Index& GetIdx ( int iCol ); }; class Cursor { friend class Table; Table m_tbl; public: Table* operator->() { return &m_tbl; } operator Table& () { return m_tbl; } }; //////////////////////////////////////////////////////////////////////////////// #define JET_DECLARE_BINDING(BaseClass) \ typedef BaseClass _JRBC; \ static const JetBlue::RecordBindingDef _jfd[]; \ private: /* Disable copy constructors... */ \ BaseClass& operator=( /*[in]*/ const BaseClass& ); \ public: \ BaseClass( /*[in]*/ const BaseClass& rs ) : RecordBindingBase( rs, this ) \ { \ } \ BaseClass( /*[in]*/ JetBlue::Table* tbl ) : RecordBindingBase( tbl, this, _jfd ) \ { \ } #define JET_BEGIN_RECORDBINDING(x) const JetBlue::RecordBindingDef x::_jfd[] = { #define JET_FIELD_BYNAME(name,type,data,flag) { name, -1 , MPC::Config::MT_##type, offsetof(_JRBC, data), offsetof(_JRBC, flag) } #define JET_FIELD_BYNAME_NOTNULL(name,type,data) { name, -1 , MPC::Config::MT_##type, offsetof(_JRBC, data), -1 } #define JET_FIELD_BYPOS(pos,type,data,flag) { NULL, pos, MPC::Config::MT_##type, offsetof(_JRBC, data), offsetof(_JRBC, flag) } #define JET_FIELD_BYPOS_NOTNULL(pos,type,data) { NULL, pos, MPC::Config::MT_##type, offsetof(_JRBC, data), -1 } #define JET_END_RECORDBINDING(x) { NULL, -1 } }; #define JET_SET_FIELD(rs,field,value) \ rs->field = value \ #define JET_SET_FIELD_TRISTATE(rs,field,validfield,value,isvalid) \ if(isvalid) \ { \ rs->field = value; \ rs->validfield = true; \ } \ else \ { \ rs->validfield = false; \ } //////////////////////////////////////////////////////////////////////////////// struct RecordBindingDef { LPCSTR szColName; int szColPos; MPC::Config::MemberTypes mtType; size_t offsetData; size_t offsetNullFlag; }; class RecordBindingBase { bool m_fInitialized; Table* m_tbl; Cursor* m_cur; void* m_pvBaseOfClass; int m_dwNumOfFields; const RecordBindingDef* m_FieldsDef; int* m_rgFieldsPos; VARTYPE* m_vtFieldsType; //////////////////// HRESULT Initialize(); void Cleanup (); HRESULT ReadData (); HRESULT WriteData(); private: // Disable copy constructors... RecordBindingBase ( /*[in]*/ const RecordBindingBase& ); RecordBindingBase& operator=( /*[in]*/ const RecordBindingBase& ); protected: RecordBindingBase( /*[in]*/ const RecordBindingBase& rs , /*[in]*/ void* pvBaseOfClass ); RecordBindingBase( /*[in]*/ Table* tbl, /*[in]*/ void* pvBaseOfClass, /*[in]*/ const RecordBindingDef* FieldsDef ); public: ~RecordBindingBase(); //////////////////// HRESULT SelectIndex ( /*[in]*/ LPCSTR szIndex, /*[in]*/ JET_GRBIT grbit = JET_bitNoMove ); HRESULT SetIndexRange( /*[in]*/ JET_GRBIT grbit = JET_bitRangeRemove ); HRESULT Move( /*[in]*/ JET_GRBIT grbit, /*[in]*/ long cRow , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek( /*[in]*/ JET_GRBIT grbit, /*[in]*/ VARIANT* rgKeys, /*[in]*/ int dwLen, /*[in]*/ bool *pfFound = NULL ); template HRESULT Seek( /*[in]*/ JET_GRBIT grbit, /*[in]*/ T value ) { CComVariant v( value ); return Seek( grbit, &v, 1 ); } //////////////////// HRESULT Insert(); HRESULT Update(); HRESULT Delete(); }; //////////////////////////////////////////////////////////////////////////////// class Database { Session* m_parent; JET_SESID m_sesid; JET_DBID m_dbid; MPC::string m_strName; TableMap m_mapTables; private: // Disable copy constructors... Database ( /*[in]*/ const Database& ); Database& operator=( /*[in]*/ const Database& ); public: Database( /*[in]*/ Session* parent, /*[in]*/ JET_SESID sesid, /*[in]*/ LPCSTR szName ); ~Database(); operator const MPC::string&() const { return m_strName; } JET_SESID GetSESID() const { return m_sesid; } JET_DBID GetDBID () const { return m_dbid; } //////////////////// HRESULT Refresh ( ); HRESULT Open ( /*[in]*/ bool fReadOnly, /*[in]*/ bool fCreate , /*[in]*/ bool fRepair ); HRESULT Close ( /*[in]*/ bool fForce = false, /*[in]*/ bool fAll = true ); HRESULT Delete ( /*[in]*/ bool fForce = false ); //////////////////// HRESULT GetTable( /*[in]*/ LPCSTR szName, /*[out]*/ Table*& tbl, /*[in]*/ JET_TABLECREATE* pDef = NULL ); HRESULT Compact(); HRESULT Repair (); //////////////////////////////////////// size_t NumOfTables() { return m_mapTables.size(); } Table* GetTbl( int iPos ); Table* GetTbl( LPCSTR szTbl ); }; //////////////////////////////////////////////////////////////////////////////// class Session { friend class SessionPool; friend class Database; SessionPool* m_parent; JET_INSTANCE m_inst; JET_SESID m_sesid; DbMap m_mapDBs; DWORD m_dwTransactionNesting; bool m_fAborted; //////////////////// bool LockDatabase ( /*[in]*/ const MPC::string& strDB, /*[in]*/ bool fReadOnly ); void UnlockDatabase ( /*[in]*/ const MPC::string& strDB ); HRESULT ReleaseDatabase( /*[in]*/ const MPC::string& strDB ); //////////////////// HRESULT Init ( ); HRESULT Close ( /*[in]*/ bool fForce = false ); void Release( ); private: // Disable copy constructors... Session ( /*[in]*/ const Session& ); Session& operator=( /*[in]*/ const Session& ); public: Session( /*[in]*/ SessionPool* parent, /*[in]*/ JET_INSTANCE inst ); ~Session(); JET_SESID GetSESID() const { return m_sesid; } //////////////////// HRESULT GetDatabase( /*[in]*/ LPCSTR szName, /*[out]*/ Database*& db, /*[in]*/ bool fReadOnly, /*[in]*/ bool fCreate, /*[in]*/ bool fRepair ); //////////////////// HRESULT BeginTransaction (); HRESULT CommitTransaction (); HRESULT RollbackTransaction(); //////////////////////////////////////// size_t NumOfDatabases() { return m_mapDBs.size(); } Database* GetDB( int iPos ); Database* GetDB( LPCSTR szDB ); }; class TransactionHandle { Session* m_sess; private: // Disable copy constructors... TransactionHandle ( /*[in]*/ const TransactionHandle& ); TransactionHandle& operator=( /*[in]*/ const TransactionHandle& ); public: TransactionHandle(); ~TransactionHandle(); HRESULT Begin ( /*[in]*/ Session* sess ); HRESULT Commit ( ); HRESULT Rollback( ); }; class SessionHandle { friend class SessionPool; SessionPool* m_pool; Session* m_sess; void Init( /*[in]*/ SessionPool* pool, /*[in]*/ Session* sess ); private: // Disable copy constructors... SessionHandle ( /*[in]*/ const SessionHandle& ); SessionHandle& operator=( /*[in]*/ const SessionHandle& ); public: SessionHandle(); ~SessionHandle(); operator Session* () const { return m_sess; } Session* operator->() const { return m_sess; } void Release(); }; class SessionPool : public CComObjectRootEx // Just to have locking... { friend class SessionHandle; friend class Session; static const int l_MaxPoolSize = 15; static const int l_MaxFreePoolSize = 5; struct SessionState { Session* m_sess; bool m_fInUse; SessionState() { m_sess = NULL; // Session* m_sess; m_fInUse = false; // bool m_fInUse; } ~SessionState() { delete m_sess; } }; struct DatabaseInUse { Session* m_sess; MPC::string m_strDB; bool m_fReadOnly; DatabaseInUse() { m_sess = NULL; // Session* m_sess; // MPC::string m_strDB; m_fReadOnly = true; // bool m_fReadOnly; } }; typedef std::list SessionList; typedef SessionList::iterator SessionIter; typedef SessionList::const_iterator SessionIterConst; typedef std::list DbInUseList; typedef DbInUseList::iterator DbInUseIter; typedef DbInUseList::const_iterator DbInUseIterConst; bool m_fInitialized; JET_INSTANCE m_inst; SessionList m_lstSessions; DbInUseList m_lstDbInUse; int m_iAllocated; int m_iInUse; //////////////////// void ReleaseSession( /*[in]*/ Session* sess ); bool LockDatabase ( /*[in]*/ Session* sess, /*[in]*/ const MPC::string& strDB, /*[in]*/ bool fReadOnly ); void UnlockDatabase( /*[in]*/ Session* sess, /*[in]*/ const MPC::string& strDB ); void Shutdown(); //////////////////// private: // Disable copy constructors... SessionPool ( /*[in]*/ const SessionPool& ); SessionPool& operator=( /*[in]*/ const SessionPool& ); public: SessionPool(); ~SessionPool(); //////////////////////////////////////////////////////////////////////////////// static SessionPool* s_GLOBAL; static HRESULT InitializeSystem(); static void FinalizeSystem (); //////////////////////////////////////////////////////////////////////////////// HRESULT Init ( /*[in]*/ LPCWSTR szLogs = NULL ); HRESULT Close( /*[in]*/ bool fForce = false ); HRESULT GetSession( /*[out]*/ SessionHandle& handle, /*[in]*/ DWORD dwTimeout = 300 ); //////////////////// HRESULT ReleaseDatabase( /*[in]*/ LPCSTR szDB ); }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// class ColumnDefinition : public MPC::Config::TypeConstructor { DECLARE_CONFIG_MAP(ColumnDefinition); public: MPC::string m_strName; DWORD m_dwColTyp; DWORD m_dwGRBits; DWORD m_dwCodePage; DWORD m_dwMax; CComVariant m_vDefault; //////////////////////////////////////// // // MPC::Config::TypeConstructor // DEFINE_CONFIG_DEFAULTTAG(); DECLARE_CONFIG_METHODS(); // //////////////////////////////////////// ColumnDefinition(); HRESULT Parse ( /*[in] */ Column& col ); HRESULT Generate( /*[out]*/ JET_COLUMNCREATE& col ); HRESULT Release ( /*[in] */ JET_COLUMNCREATE& col ); }; //////////////////////////////////////// class IndexDefinition : public MPC::Config::TypeConstructor { DECLARE_CONFIG_MAP(IndexDefinition); public: MPC::string m_strName; MPC::string m_strCols; DWORD m_dwGRBits; DWORD m_dwDensity; //////////////////////////////////////// // // MPC::Config::TypeConstructor // DEFINE_CONFIG_DEFAULTTAG(); DECLARE_CONFIG_METHODS(); // //////////////////////////////////////// IndexDefinition(); HRESULT Parse ( /*[in] */ Index& idx ); HRESULT Generate( /*[out]*/ JET_INDEXCREATE& idx ); HRESULT Release ( /*[in] */ JET_INDEXCREATE& idx ); }; typedef std::list< ColumnDefinition > ColDefList; typedef ColDefList::iterator ColDefIter; typedef ColDefList::const_iterator ColDefIterConst; typedef std::list< IndexDefinition > IdxDefList; typedef IdxDefList::iterator IdxDefIter; typedef IdxDefList::const_iterator IdxDefIterConst; class TableDefinition : public MPC::Config::TypeConstructor { //////////////////////////////////////// DECLARE_CONFIG_MAP(TableDefinition); public: MPC::string m_strName; DWORD m_dwPages; DWORD m_dwDensity; ColDefList m_lstColumns; IdxDefList m_lstIndexes; //////////////////////////////////////// // // MPC::Config::TypeConstructor // DEFINE_CONFIG_DEFAULTTAG(); DECLARE_CONFIG_METHODS(); // //////////////////////////////////////// TableDefinition(); HRESULT Load( /*[in]*/ LPCWSTR szFile ); HRESULT Save( /*[in]*/ LPCWSTR szFile ); HRESULT Parse ( /*[in] */ Table& tbl ); HRESULT Generate( /*[out]*/ JET_TABLECREATE& tbl ); HRESULT Release ( /*[in] */ JET_TABLECREATE& tbl ); }; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// #ifndef NOJETBLUECOM namespace JetBlueCOM { class Column; class Index; class Table; class Database; class Session; typedef MPC::CComObjectParent Session_Object; typedef MPC::CComObjectParent Database_Object; typedef MPC::CComObjectParent Table_Object; typedef CComObject Column_Object; typedef CComObject Index_Object; //////////////////////////////////////////////////////////////////////////////// template class BaseObjectWithChildren { public: typedef std::list ChildList; typedef ChildList::iterator ChildIter; typedef ChildList::const_iterator ChildIterConst; private: ChildList m_children; private: // Disable copy constructors... BaseObjectWithChildren ( /*[in]*/ const BaseObjectWithChildren& ); BaseObjectWithChildren& operator=( /*[in]*/ const BaseObjectWithChildren& ); public: BaseObjectWithChildren() { } virtual ~BaseObjectWithChildren() { Passivate(); } void GetChildren( /*[out]*/ ChildIterConst& itBegin, /*[out]*/ ChildIterConst& itEnd ) { itBegin = m_children.begin(); itEnd = m_children.end (); } //////////////////////////////////////// HRESULT CreateChild( Parent* pParent, Child* *pVal ) { __HCP_FUNC_ENTRY( "CreateChild" ); HRESULT hr; ChildIter it; CComObject* pChild = NULL; __MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL); __MPC_PARAMCHECK_END(); __MPC_EXIT_IF_METHOD_FAILS(hr, pChild->CreateInstance( &pChild )); m_children.push_back( pChild ); pChild->AddRef(); *pVal = pChild; pChild->AddRef(); hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } void Passivate() { ChildIter it; for(it = m_children.begin(); it != m_children.end(); it++) { Child* child = *it; child->Passivate(); child->Release (); } m_children.clear(); } HRESULT GetEnumerator( /*[in]*/ IPCHDBCollection* *pVal ) { __HCP_FUNC_ENTRY( "GetEnumerator" ); HRESULT hr; ChildIter it; CComObject* pColl = NULL; __MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL); __MPC_PARAMCHECK_END(); // // Create a new collection. // __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->CreateInstance( &pColl )); pColl->AddRef(); for(it = m_children.begin(); it != m_children.end(); it++) { __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->AddItem( *it )); } __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->QueryInterface( IID_IPCHDBCollection, (void**)pVal )); hr = S_OK; __HCP_FUNC_CLEANUP; if(pColl) pColl->Release(); __HCP_FUNC_EXIT(hr); } }; //////////////////////////////////////// typedef MPC::CComCollection BaseCollection; class ATL_NO_VTABLE Collection : // Hungarian: hcpc public BaseCollection { public: BEGIN_COM_MAP(Collection) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IPCHDBCollection) END_COM_MAP() // // This is a trick! // // MPC::CComCollection defined a "get_Item" method that has a different signature from the // one in IPCHDBCollection, so it's not callable from scripting. Instead, this method will // be called. // STDMETHOD(get_Item)( /*[in]*/ VARIANT Index, /*[out]*/ VARIANT* pvar ) { HRESULT hr = E_FAIL; //Index is 1-based if(pvar == NULL) return E_POINTER; if(Index.vt == VT_I4) { return BaseCollection::get_Item( (long)Index.iVal, pvar ); } else if(Index.vt == VT_BSTR && Index.bstrVal) { std::list< VARIANT >::iterator iter; for(iter = m_coll.begin(); iter != m_coll.end(); iter++) { CComDispatchDriver disp( iter->pdispVal ); CComVariant v; if(SUCCEEDED(disp.GetPropertyByName( L"Name", &v )) && SUCCEEDED(v .ChangeType ( VT_BSTR )) ) { if(v.bstrVal && !wcscmp( v.bstrVal, Index.bstrVal )) { hr = _Copy< VARIANT >::copy( pvar, &*iter ); break; } } } } return hr; } }; //////////////////////////////////////////////////////////////////////////////// class ATL_NO_VTABLE Column : public CComObjectRootEx, public IDispatchImpl { JetBlue::Column* m_col; public: BEGIN_COM_MAP(Column) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IPCHDBColumn) END_COM_MAP() Column(); virtual ~Column(); HRESULT Initialize( /*[in]*/ JetBlue::Column& col ); void Passivate ( ); //////////////////////////////////////// STDMETHOD(get_Name )( /*[out, retval]*/ BSTR *pVal ); STDMETHOD(get_Type )( /*[out, retval]*/ long *pVal ); STDMETHOD(get_Bits )( /*[out, retval]*/ long *pVal ); STDMETHOD(get_Value)( /*[out, retval]*/ VARIANT *pVal ); STDMETHOD(put_Value)( /*[in] */ VARIANT newVal ); }; class ATL_NO_VTABLE Index : public CComObjectRootEx, public IDispatchImpl { JetBlue::Index* m_idx; BaseObjectWithChildren m_Columns; public: BEGIN_COM_MAP(Index) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IPCHDBIndex) END_COM_MAP() Index(); virtual ~Index(); HRESULT Initialize( /*[in]*/ JetBlue::Index& idx ); void Passivate ( ); //////////////////////////////////////// STDMETHOD(get_Name )( /*[out, retval]*/ BSTR *pVal ); STDMETHOD(get_Columns)( /*[out, retval]*/ IPCHDBCollection* *pVal ); }; class ATL_NO_VTABLE Table : public CComObjectRootEx, public IDispatchImpl { JetBlue::Table* m_tbl; BaseObjectWithChildren m_Columns; BaseObjectWithChildren m_Indexes; public: BEGIN_COM_MAP(Table) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IPCHDBTable) END_COM_MAP() Table(); virtual ~Table(); HRESULT Initialize( /*[in]*/ JetBlue::Table& tbl ); void Passivate ( ); //////////////////////////////////////// STDMETHOD(get_Name )( /*[out, retval]*/ BSTR *pVal ); STDMETHOD(get_Columns)( /*[out, retval]*/ IPCHDBCollection* *pVal ); STDMETHOD(get_Indexes)( /*[out, retval]*/ IPCHDBCollection* *pVal ); //////////////////// STDMETHOD(SelectIndex )( /*[in]*/ BSTR bstrIndex, /*[in]*/ long grbit ); STDMETHOD(SetIndexRange)( /*[in]*/ long grbit ); STDMETHOD(PrepareInsert)(); STDMETHOD(PrepareUpdate)(); STDMETHOD(Move)( /*[in]*/ long grbit, /*[in]*/ long cRow, /*[out, retval]*/ VARIANT_BOOL *pfValid ); STDMETHOD(Seek)( /*[in]*/ long grbit, /*[in]*/ VARIANT vKey, /*[out, retval]*/ VARIANT_BOOL *pfValid ); STDMETHOD(UpdateRecord)(); STDMETHOD(DeleteRecord)(); }; class ATL_NO_VTABLE Database : public CComObjectRootEx, public IDispatchImpl { JetBlue::Database* m_db; BaseObjectWithChildren m_Tables; HRESULT Refresh(); public: BEGIN_COM_MAP(Database) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IPCHDBDatabase) END_COM_MAP() Database(); virtual ~Database(); HRESULT Initialize( /*[in]*/ JetBlue::Database& db ); void Passivate ( ); //////////////////////////////////////// STDMETHOD(get_Name )( /*[out, retval]*/ BSTR *pVal ); STDMETHOD(get_Tables)( /*[out, retval]*/ IPCHDBCollection* *pVal ); STDMETHOD(AttachTable)( /*[in]*/ BSTR bstrName, /*[in, optional]*/ VARIANT bstrXMLDef, /*[out,retval]*/ IPCHDBTable* *pVal ); }; class ATL_NO_VTABLE Session : public CComObjectRootEx, public CComCoClass, public IDispatchImpl { JetBlue::SessionHandle m_sess; BaseObjectWithChildren m_DBs; HRESULT Refresh(); public: DECLARE_REGISTRY_RESOURCEID(IDR_PCHDBSESSION) DECLARE_NOT_AGGREGATABLE(Session) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(Session) COM_INTERFACE_ENTRY(IDispatch) COM_INTERFACE_ENTRY(IPCHDBSession) END_COM_MAP() Session(); virtual ~Session(); HRESULT FinalConstruct(); void Passivate (); //////////////////////////////////////// STDMETHOD(get_Databases)( /*[out, retval]*/ IPCHDBCollection* *pVal ); STDMETHOD(AttachDatabase)( /*[in]*/ BSTR bstrName, /*[in, optional]*/ VARIANT fCreate, /*[out,retval]*/ IPCHDBDatabase* *pVal ); STDMETHOD(BeginTransaction )(); STDMETHOD(CommitTransaction )(); STDMETHOD(RollbackTransaction)(); }; }; #endif //////////////////////////////////////////////////////////////////////////////// namespace Taxonomy { struct RS_Data_DBParameters { MPC::wstring m_strName; MPC::wstring m_strValue; bool m_fValid__Value; }; class RS_DBParameters : public JetBlue::RecordBindingBase, public RS_Data_DBParameters { JET_DECLARE_BINDING(RS_DBParameters); public: HRESULT Seek_ByName( /*[in]*/ LPCWSTR szName, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_ContentOwners { MPC::wstring m_strDN; long m_ID_owner; bool m_fIsOEM; }; class RS_ContentOwners : public JetBlue::RecordBindingBase, public RS_Data_ContentOwners { JET_DECLARE_BINDING(RS_ContentOwners); public: HRESULT Seek_ByVendorID( /*[in]*/ LPCWSTR szDN, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_SynSets { MPC::wstring m_strName; long m_ID_owner; long m_ID_synset; }; class RS_SynSets : public JetBlue::RecordBindingBase, public RS_Data_SynSets { JET_DECLARE_BINDING(RS_SynSets); public: HRESULT Seek_ByPair( /*[in]*/ LPCWSTR szName, /*[in]*/ long ID_owner, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_HelpImage { long m_ID_owner; MPC::wstring m_strFile; }; class RS_HelpImage : public JetBlue::RecordBindingBase, public RS_Data_HelpImage { JET_DECLARE_BINDING(RS_HelpImage); public: HRESULT Seek_ByFile( /*[in]*/ LPCWSTR szFile, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_Scope { long m_ID_scope ; long m_ID_owner ; MPC::wstring m_strID ; MPC::wstring m_strName ; MPC::wstring m_strCategory; bool m_fValid__Category; // Warning!! Long Text columns cannot be NOT NULL.... }; class RS_Scope : public JetBlue::RecordBindingBase, public RS_Data_Scope { JET_DECLARE_BINDING(RS_Scope); public: HRESULT Seek_ByID ( /*[in]*/ LPCWSTR szID , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_ByScope ( /*[in]*/ long ID_scope, /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_OwnedScopes( /*[in]*/ long ID_owner, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_IndexFiles { long m_ID_owner; long m_ID_scope; MPC::wstring m_strStorage; bool m_fValid__Storage; MPC::wstring m_strFile; bool m_fValid__File; }; class RS_IndexFiles : public JetBlue::RecordBindingBase, public RS_Data_IndexFiles { JET_DECLARE_BINDING(RS_IndexFiles); public: HRESULT Seek_ByScope( /*[in]*/ long ID_scope, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_FullTextSearch { long m_ID_owner; long m_ID_scope; MPC::wstring m_strCHM ; bool m_fValid__CHM; MPC::wstring m_strCHQ ; bool m_fValid__CHQ; }; class RS_FullTextSearch : public JetBlue::RecordBindingBase, public RS_Data_FullTextSearch { JET_DECLARE_BINDING(RS_FullTextSearch); public: HRESULT Seek_ByScope( /*[in]*/ long ID_scope, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_Taxonomy { long m_ID_node ; long m_lPos ; long m_ID_parent ; bool m_fValid__ID_parent ; long m_ID_owner ; MPC::wstring m_strEntry ; MPC::wstring m_strTitle ; bool m_fValid__Title ; // Warning!! Long Text columns cannot be NOT NULL.... MPC::wstring m_strDescription ; bool m_fValid__Description ; MPC::wstring m_strDescriptionURI; bool m_fValid__DescriptionURI; MPC::wstring m_strIconURI ; bool m_fValid__IconURI ; bool m_fVisible ; bool m_fSubsite ; long m_lNavModel ; friend HRESULT operator>>( /*[in]*/ MPC::Serializer& stream, /*[out]*/ RS_Data_Taxonomy& val ); friend HRESULT operator<<( /*[in]*/ MPC::Serializer& stream, /*[in] */ const RS_Data_Taxonomy& val ); }; class RS_Taxonomy : public JetBlue::RecordBindingBase, public RS_Data_Taxonomy { JET_DECLARE_BINDING(RS_Taxonomy); public: HRESULT Seek_SubNode ( /*[in]*/ long ID_parent, /*[in]*/ LPCWSTR szEntry, /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_ChildrenSorted( /*[in]*/ long ID_parent, /*[in]*/ long lPos , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_Children ( /*[in]*/ long ID_parent , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_Node ( /*[in]*/ long ID_node , /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_Topics { long m_ID_topic ; long m_ID_node ; long m_ID_owner ; long m_lPos ; MPC::wstring m_strTitle ; bool m_fValid__Title ; // Warning!! Long Text columns cannot be NOT NULL.... MPC::wstring m_strURI ; bool m_fValid__URI ; // Warning!! Long Text columns cannot be NOT NULL.... MPC::wstring m_strDescription; bool m_fValid__Description; MPC::wstring m_strIconURI ; bool m_fValid__IconURI ; long m_lType ; bool m_fVisible ; }; class RS_Topics : public JetBlue::RecordBindingBase, public RS_Data_Topics { JET_DECLARE_BINDING(RS_Topics); public: HRESULT Seek_SingleTopic ( /*[in]*/ long ID_topic, /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_TopicsUnderNode( /*[in]*/ long ID_node , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_ByURI ( /*[in]*/ LPCWSTR szURI, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_Synonyms { MPC::wstring m_strKeyword; long m_ID_synset; long m_ID_owner; }; class RS_Synonyms : public JetBlue::RecordBindingBase, public RS_Data_Synonyms { JET_DECLARE_BINDING(RS_Synonyms); public: HRESULT Seek_ByPair( /*[in]*/ LPCWSTR szKeyword, /*[in]*/ long ID_synset, /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_ByName( /*[in]*/ LPCWSTR szKeyword, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_Keywords { MPC::wstring m_strKeyword; long m_ID_keyword; }; class RS_Keywords : public JetBlue::RecordBindingBase, public RS_Data_Keywords { JET_DECLARE_BINDING(RS_Keywords); public: HRESULT Seek_ByName( /*[in]*/ LPCWSTR szKeyword, /*[in]*/ bool *pfFound = NULL ); }; //////////////////// struct RS_Data_Matches { long m_ID_topic ; long m_ID_keyword; long m_lPriority ; bool m_fHHK ; }; class RS_Matches : public JetBlue::RecordBindingBase, public RS_Data_Matches { JET_DECLARE_BINDING(RS_Matches); public: HRESULT Seek_Pair ( /*[in]*/ long ID_Keyword, /*[in]*/ long ID_topic, /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_ByKeyword( /*[in]*/ long ID_Keyword , /*[in]*/ bool *pfFound = NULL ); HRESULT Seek_ByTopic ( /*[in]*/ long ID_topic , /*[in]*/ bool *pfFound = NULL ); }; //////////////////////////////////////////////////////////////////////////////// HRESULT CreateSchema( /*[in]*/ JetBlue::Database* db ); extern const int g_NumOfTables; extern const JET_TABLECREATE* g_Tables[]; }; //////////////////////////////////////////////////////////////////////////////// #endif // !defined(__INCLUDED___HCP___JETBLUELIB_H___)