//+-------------------------------------------------------------------------- // // Copyright (c) 1997-1999 Microsoft Corporation // // File: // // Contents: // // History: // //--------------------------------------------------------------------------- #ifndef __JETBLUE_H__ #define __JETBLUE_H__ #include "JBDef.h" #include "locks.h" #define JETBLUE_EDBLOG _TEXT("edb*.log") #define JETBLUE_RESLOG _TEXT("res?.log") class JBError; class JBSession; class JBDatabase; class JBTable; class JBColumn; // class JBIndex; // class JBRecordSet; // ///////////////////////////////////////////////////////////////////// // class JBInstance : public JBError { friend class JBSession; friend operator==(const JBInstance& jbInst1, const JBInstance& jbInst2); friend operator!=(const JBInstance& jbInst1, const JBInstance& jbInst2); private: JET_INSTANCE m_JetInstance; // DWORD m_NumSession; CSafeCounter m_NumSession; BOOL m_bInit; private: JET_SESID BeginJetSession( LPCTSTR pszUserName=NULL, LPCTSTR pszPwd=NULL ); BOOL EndJetSession( JET_SESID JetSessionID, JET_GRBIT grbit = 0 ); BOOL EndSession( JET_SESID sesId, JET_GRBIT grbit ); public: JBInstance(); ~JBInstance(); BOOL SetSystemParameter( JET_SESID SesId, unsigned long lParamId, ULONG_PTR lParam, PBYTE sz ); BOOL GetSystemParameter( JET_SESID SesId, unsigned long lParamId, ULONG_PTR* plParam, PBYTE sz, unsigned long cbMax ); const JET_INSTANCE GetInstanceID() const { return m_JetInstance; } BOOL JBInitJetInstance(); BOOL JBTerminate( JET_GRBIT grbit = JET_bitTermComplete, BOOL bDeleteLogFile = FALSE ); BOOL IsValid() const { return m_bInit; } }; //-------------------------------------------------------------------- inline BOOL operator==( const JBInstance& jbInst1, const JBInstance& jbInst2 ) { return jbInst1.GetInstanceID() == jbInst2.GetInstanceID(); } inline BOOL operator!=( const JBInstance& jbInst1, const JBInstance& jbInst2 ) { return !(jbInst1 == jbInst2); } // ///////////////////////////////////////////////////////////////////// // class JBSession : public JBError { friend class JBDatabase; private: JBInstance& m_JetInstance; JET_SESID m_JetSessionID; // JetBlue Transaction is session base int m_TransactionLevel; // DWORD m_JetDBInitialized; CSafeCounter m_JetDBInitialized; // CCriticalSection m_JetSessionLock; private: JET_DBID OpenJetDatabase( LPCTSTR szDatabase, LPCTSTR szConnect=NULL, JET_GRBIT grbit=0 ); BOOL CloseJetDatabase( JET_DBID jdbId, JET_GRBIT grbit=0 ); JET_DBID CreateJetDatabase( LPCTSTR szFileName, LPCTSTR szConnect=NULL, JET_GRBIT grbit=0 ); BOOL DuplicateSession( JET_SESID sesID ); JBInstance& GetJetInstance() { return m_JetInstance; } BOOL CloseDatabase( JET_DBID jdbId, JET_GRBIT grbit=0 ); public: JBSession(JBSession& JetSession); // JetDupSession() JBSession( JBInstance& JetInstance, JET_SESID JetSessID=JET_sesidNil ); ~JBSession(); BOOL IsValid() const { return m_JetInstance.IsValid() && m_JetSessionID != JET_sesidNil; } BOOL BeginSession( LPCTSTR szUserName=NULL, LPCTSTR szPwd=NULL ); BOOL EndSession( JET_GRBIT grbit = JET_bitTermComplete ); const JBInstance& GetJetInstance() const { return m_JetInstance; } const JET_SESID GetJetSessionID() const { return m_JetSessionID; } BOOL SetSystemParameter( unsigned long lParamId, ULONG_PTR lParam, const PBYTE sz ); BOOL GetSystemParameter( unsigned long lParamId, ULONG_PTR* plParam, PBYTE sz, unsigned long cbMax ); // // make JetBlue aware of database // BOOL AttachDatabase( LPCTSTR szFileName, JET_GRBIT grbit=0 ); BOOL DetachDatabase( LPCTSTR szFileName ); // // Transaction // BOOL BeginTransaction(); BOOL CommitTransaction(JET_GRBIT grbit=0); BOOL RollbackTransaction(JET_GRBIT grbit=JET_bitRollbackAll); int GetTransactionLevel() const { return m_TransactionLevel; } BOOL EndAllTransaction( BOOL bCommit=FALSE, JET_GRBIT grbit=0 ); BOOL Compatible(const JBSession& jbSess) const { return GetJetInstance() == jbSess.GetJetInstance(); } //CCriticalSection& //GetSessionLock() //{ // return m_JetSessionLock; //} }; // ///////////////////////////////////////////////////////////////////// // class JBDatabase : public JBError { friend class JBTable; private: JBSession& m_JetSession; TCHAR m_szDatabaseFile[MAX_PATH+1]; CSafeCounter m_TableOpened; // DWORD m_TableOpened; JET_DBID m_JetDbId; private: JET_TABLEID OpenJetTable( LPCTSTR pszTableName, void* pvParam=NULL, unsigned long cbParam=0, JET_GRBIT grbit=JET_bitTableUpdatable ); JET_TABLEID DuplicateJetCursor( // JET_SESID sesId, JET_TABLEID tableid, JET_GRBIT grbit=0 // must be zero ); JET_TABLEID CreateJetTable( LPCTSTR pszTableName, unsigned long lPage=0, unsigned long lDensity=20 ); BOOL CloseJetTable( // JET_SESID sesId, JET_TABLEID tableid ); JET_TABLEID CreateJetTableEx( LPCTSTR pszTableName, const PTLSJBTable table_attribute, const PTLSJBColumn columns, const DWORD num_columns, const PTLSJBIndex index, const DWORD num_index ); BOOL CloseTable( JET_TABLEID tableid ); public: JBDatabase( JBSession& jbSession, JET_DBID jdbId=JET_dbidNil, LPCTSTR pszDatabase=NULL ); ~JBDatabase(); BOOL IsValid() const { return m_JetSession.IsValid() && m_JetDbId != JET_dbidNil; } const JBSession& GetJetSession() const { return m_JetSession; } const JET_SESID GetJetSessionID() const { return m_JetSession.GetJetSessionID(); } const JET_DBID GetJetDatabaseID() const { return m_JetDbId; } BOOL Compatible(const JBDatabase& jbDatabase) const { return GetJetSession().Compatible(jbDatabase.GetJetSession()); } LPCTSTR GetDatabaseName() const { return m_szDatabaseFile; } BOOL OpenDatabase( LPCTSTR szDatabase, LPCTSTR szConnect=NULL, JET_GRBIT grbit=0 ); BOOL CreateDatabase( LPCTSTR szDatabase, LPCTSTR szConnect=NULL, JET_GRBIT grbit=0 ); BOOL CloseDatabase( JET_GRBIT grbit=0 ); BOOL DeleteTable( LPCTSTR pszTableName ); // // tableid return from JetCreateTable is not usable // JET_TABLEID CreateTable( LPCTSTR pszTableName, unsigned long lPage=0, unsigned long lDensity=20 ); JET_TABLEID CreateTableEx( LPCTSTR pszTableName, const PTLSJBTable table_attribute, const PTLSJBColumn columns, DWORD num_columns, const PTLSJBIndex index, DWORD num_index ); //JBTable* //CreateTable( // LPCTSTR pszTableName, // unsigned long lPage=0, // unsigned long lDensity=20 //); //JBTable* //CreateTableEx( // LPCTSTR pszTableName, // const PTLSJBTable table_attribute, // const PTLSJBColumn columns, // DWORD num_columns, // const PTLSJBIndex index, // DWORD num_index //); // // Transaction // BOOL BeginTransaction() { return m_JetSession.BeginTransaction(); } BOOL CommitTransaction(JET_GRBIT grbit=0) { return m_JetSession.CommitTransaction(grbit); } BOOL RollbackTransaction(JET_GRBIT grbit=JET_bitRollbackAll) { return m_JetSession.RollbackTransaction(grbit); } int GetTransactionLevel() const { return m_JetSession.GetTransactionLevel(); } //CCriticalSection& //GetSessionLock() { // return m_JetSession.GetSessionLock(); //} }; // ///////////////////////////////////////////////////////////////////// // // Pure virtual base struct for index // struct JBKeyBase { BOOL m_EmptyValue; JBKeyBase() : m_EmptyValue(TRUE) {} void SetEmptyValue(BOOL bEmpty) { m_EmptyValue = bEmpty; } virtual JET_GRBIT GetJetGrbit() { return JET_bitIndexIgnoreNull; } virtual unsigned long GetJetDensity() { return TLS_TABLE_INDEX_DEFAULT_DENSITY; } virtual BOOL IsEmptyValue() { return m_EmptyValue; } virtual DWORD GetKeyLength() { LPCTSTR pszIndexKey = GetIndexKey(); DWORD keylength; // calculate index key length, terminated with double 0 keylength = 2; while(pszIndexKey[keylength-1] != _TEXT('\0') || pszIndexKey[keylength-2] != _TEXT('\0')) { if(keylength >= TLS_JETBLUE_MAX_INDEXKEY_LENGTH) { DebugBreak(); // error return TLS_JETBLUE_MAX_INDEXKEY_LENGTH; } keylength++; } return keylength; } // ---------------------------------------------------- // Virtual function must be implemented // ---------------------------------------------------- virtual BOOL GetSearchKey( DWORD dwComponentIndex, PVOID* pbData, unsigned long* cbData, JET_GRBIT* grbit, DWORD dwSearchType )=0; virtual LPCTSTR GetIndexName()=0; virtual LPCTSTR GetIndexKey() = 0; virtual DWORD GetNumKeyComponents() = 0; }; // ///////////////////////////////////////////////////////////////////// // struct JBIndexStructBase { virtual LPCTSTR GetIndexName() = 0; virtual LPCTSTR GetIndexKey() = 0; virtual DWORD GetNumKeyComponent() = 0; virtual BOOL GetSearchKey( DWORD dwComponentIndex, PVOID* pbData, unsigned long* cbData, JET_GRBIT* grbit, DWORD dwSearchType ) = 0; }; // ///////////////////////////////////////////////////////////////////// // class JBTable : public JBError { friend class JBDatabase; private: static JBColumn m_ErrColumn; JBDatabase& m_JetDatabase; TCHAR m_szTableName[MAX_TABLENAME_LENGTH+1]; JET_TABLEID m_JetTableId; typedef struct JetColumns { TCHAR pszColumnName[MAX_JETBLUE_NAME_LENGTH]; JET_COLTYP colType; JET_COLUMNID colId; unsigned long cbMaxLength; // max length of column JET_GRBIT jbGrbit; } JetColumns, *PJetColumns; //PJetColumns m_Columns; //int m_NumColumns; JBColumn* m_JetColumns; int m_NumJetColumns; BOOL m_InEnumeration; BOOL m_InsertRepositionBookmark; private: JBDatabase& GetJetDatabase() { return m_JetDatabase; } JET_COLUMNID AddJetColumn( LPCTSTR pszColumnName, const JET_COLUMNDEF* pColumnDef, const PVOID pbDefaultValue=NULL, const unsigned long cbDefaultValue=0 ); BOOL LoadTableInfo(); public: void SetInsertRepositionBookmark( BOOL bRepo ) /*++ --*/ { m_InsertRepositionBookmark = bRepo; return; } typedef enum { ENUM_ERROR=0, ENUM_SUCCESS, ENUM_END, ENUM_CONTINUE } ENUM_RETCODE; int GetNumberOfColumns() { return m_NumJetColumns; } JBTable( JBDatabase& JetDatabase, LPCTSTR pszTableName=NULL, JET_TABLEID tableid=JET_tableidNil ); JBTable( JBTable& jbTable ); ~JBTable(); BOOL IsValid() const { return m_JetTableId != JET_tableidNil && m_JetDatabase.IsValid(); } const JBDatabase& GetJetDatabase() const { return m_JetDatabase; } const JET_TABLEID GetJetTableID() const { return m_JetTableId; } const JET_SESID GetJetSessionID() const { return m_JetDatabase.GetJetSessionID(); } const JET_DBID GetJetDatabaseID() const { return m_JetDatabase.GetJetDatabaseID(); } LPCTSTR GetTableName() const { return m_szTableName; } JBTable* DuplicateCursor( JET_GRBIT grbit=0 ); JBTable& operator=(const JBTable& srcTable); BOOL CloseTable(); BOOL CreateOpenTable( LPCTSTR pszTableName, unsigned long lPage=0, unsigned long lDensity=20 ); BOOL OpenTable( LPCTSTR pszTableName, void* pvParam=NULL, unsigned long cbParam=0, JET_GRBIT grbit=0 ); BOOL AddIndex( JBKeyBase* key ); int AddIndex( int numIndex, PTLSJBIndex pIndex ); BOOL DoesIndexExist( LPCTSTR pszIndexName ); int AddColumn( int numColumns, PTLSJBColumn pColumnDef ); BOOL AddJetIndex( LPCTSTR pszIndexName, LPCTSTR pszKey, unsigned long cbKey, JET_GRBIT jetGrbit, unsigned long lDensity=20 ); // ---------------------------------------------- // Transaction // ---------------------------------------------- BOOL BeginTransaction() { return m_JetDatabase.BeginTransaction(); } BOOL CommitTransaction(JET_GRBIT grbit=0) { return m_JetDatabase.CommitTransaction(grbit); } BOOL RollbackTransaction(JET_GRBIT grbit=JET_bitRollbackAll) { return m_JetDatabase.RollbackTransaction(grbit); } int GetTransactionLevel() const { return m_JetDatabase.GetTransactionLevel(); } JBColumn* FindColumnByName(LPCTSTR pszColumnName); JBColumn* FindColumnByIndex(const int index); JBColumn* FindColumnByColumnId(const JET_COLUMNID); #if 1 JBColumn& operator[](LPCTSTR pszColumnName) { JBColumn* jb = FindColumnByName(pszColumnName); return (jb) ? *jb : m_ErrColumn; } JBColumn& operator[](const int index) { JBColumn* jb = FindColumnByIndex(index); return (jb) ? *jb : m_ErrColumn; } JBColumn& operator[](const JET_COLUMNID jetid) { JBColumn* jb = FindColumnByColumnId(jetid); return (jb) ? *jb : m_ErrColumn; } #else JBColumn* operator[](LPCTSTR pszColumnName) { return FindColumn(pszColumnName); } JBColumn* operator[](const int index) { return FindColumn(index); } JBColumn* operator[](const JET_COLUMNID jetid) { return FindColumn(jetid); } #endif JET_COLUMNID GetJetColumnID(LPCTSTR pszColumnName); int GetJetColumnIndex(LPCTSTR pszColumnName); BOOL ReadLock(); BOOL WriteLock(); BOOL BeginUpdate(BOOL bUpdate = FALSE); BOOL EndUpdate( BOOL bDiscard = FALSE ); BOOL SeekToKey( JBKeyBase* key, DWORD dwSearchType, JET_GRBIT jet_seek_grbit=JET_bitSeekGE ); BOOL RetrieveKey( PVOID pbData, unsigned long cbData, unsigned long* pcbActual=NULL, JET_GRBIT grbit=0 ); // // Enumeration // BOOL EnumBegin( LPCTSTR pszIndexName=NULL, // enumeration thru primary index JET_GRBIT grbit=JET_bitMoveFirst ); BOOL MoveToRecord( long crow=JET_MoveNext, JET_GRBIT grbit=0 ); BOOL EnumBegin( JBKeyBase* key, DWORD dwParam=0 ); ENUM_RETCODE EnumNext( JET_GRBIT crow=JET_MoveNext, JET_GRBIT grbit=0 //JET_bitMoveKeyNE // limit our traveral to index ); void EnumEnd() { m_InEnumeration = FALSE; } //----------------------------------------------------------- BOOL SetCurrentIndex( LPCTSTR pszIndexName, JET_GRBIT grbit = JET_bitMoveFirst ); //----------------------------------------------------------- BOOL GetCurrentIndex( LPTSTR pszIndexName, unsigned long* bufferSize ); BOOL EndOfRecordSet() { return m_JetErr == JET_errNoCurrentRecord; } unsigned long GetIndexRecordCount( unsigned long max=0xFFFFFFFF ); BOOL MakeKey( PVOID pbData, unsigned long cbData, JET_GRBIT grbit=JET_bitNewKey ); BOOL SeekValue(JET_GRBIT grbit=JET_bitSeekEQ); BOOL SeekValueEx( PVOID pbData, unsigned long cbData, JET_GRBIT keyGrbit, JET_GRBIT seekGrbit ) /* Only work for single component key */ { if(MakeKey(pbData, cbData, keyGrbit) == FALSE) return FALSE; return SeekValue(seekGrbit); } BOOL DeleteRecord(); BOOL GetBookmark( PVOID pbBookmark, PDWORD pcbBookmark ); BOOL GotoBookmark( PVOID pbBookmark, DWORD cbBookmark ); //CCriticalSection& //GetSessionLock() { // return m_JetDatabase.GetSessionLock(); //} }; //------------------------------------------------------------------------ struct JBColumnBufferBase { virtual PVOID GetInputBuffer() = 0; virtual PVOID GetOutputBuffer() = 0; virtual DWORD GetInputBufferLength() = 0; virtual DWORD GetOutputBufferLength() = 0; }; //------------------------------------------------------------------------ class JBColumn : public JBError { friend class JBTable; private: JBTable* m_pJetTable; TCHAR m_szColumnName[MAX_JETBLUE_NAME_LENGTH+1]; JET_COLUMNID m_JetColId; JET_COLTYP m_JetColType; unsigned long m_JetMaxColLength; JET_GRBIT m_JetGrbit; PVOID m_pbDefValue; int m_cbDefValue; unsigned long m_JetColCodePage; unsigned long m_JetColCountryCode; unsigned long m_JetColLangId; unsigned long m_cbActual; JET_RETINFO m_JetRetInfo; BOOL m_JetNullColumn; //------------------------------------------------------------- void Cleanup(); BOOL LoadJetColumnInfoFromJet( const JET_COLUMNLIST* column ); JET_ERR RetrieveColumnValue( JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, PVOID pbBuffer, unsigned long cbBuffer, unsigned long offset=0 ); void AttachToTable( JBTable* pJetTable ) { m_pJetTable = pJetTable; return; } public: JBColumn(JBTable* pJetTable=NULL); ~JBColumn() {} const unsigned long GetMaxColumnLength() const { return m_JetMaxColLength; } BOOL IsValid() const; const JET_COLTYP GetJetColumnType() const { return m_JetColType; } const JET_COLUMNID GetJetColumnID() const { return m_JetColId; } const JET_SESID GetJetSessionID() const { return (m_pJetTable) ? m_pJetTable->GetJetSessionID() : JET_sesidNil; } const JET_TABLEID GetJetTableID() const { return (m_pJetTable) ? m_pJetTable->GetJetTableID() : JET_tableidNil; } LPCTSTR GetJetColumnName() const { return (IsValid()) ? m_szColumnName : NULL; } const JBTable* GetJetTable() const { return m_pJetTable; } // // TODO - append to long binary column // BOOL InsertColumn( PVOID pbData, unsigned long cbData, unsigned long starting_offset=0 ); BOOL FetchColumn( PVOID pbData, unsigned long cbData, unsigned long starting_offset=0 // for future enhancement ); void SetRetrieveOffset( unsigned long offset ) { m_JetRetInfo.ibLongValue = offset; } JBTable* GetWorkingTable() { return m_pJetTable; } unsigned long GetDataSize() { return m_cbActual; } //----------------------------------------------- BOOL FetchColumn( JBColumnBufferBase* pBuffer, DWORD offset=0 ) /* */ { return FetchColumn( pBuffer->GetInputBuffer(), pBuffer->GetInputBufferLength(), offset ); } BOOL InsertColumn( JBColumnBufferBase* pBuffer, DWORD offset=0 ) /* */ { return FetchColumn( pBuffer->GetOutputBuffer(), pBuffer->GetOutputBufferLength(), offset ); } }; #endif