Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1153 lines
21 KiB

//+--------------------------------------------------------------------------
//
// 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