QueryDef.cpp
资源名称:querydef.zip [点击查看]
上传用户:yunnanyeer
上传日期:2007-01-03
资源大小:86k
文件大小:32k
源码类别:
数据库编程
开发平台:
Visual C++
- // QueryDef.cpp : Defines the initialization routines for the DLL.
- //
- #include "stdafx.h"
- #include <afxdllx.h>
- #include "QueryDef.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- static AFX_EXTENSION_MODULE QueryDefDLL = { NULL, NULL };
- extern "C" int APIENTRY
- DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
- {
- UNREFERENCED_PARAMETER(lpReserved);
- if (dwReason == DLL_PROCESS_ATTACH)
- {
- TRACE0("QUERYDEF.DLL Initializing!n");
- if (!AfxInitExtensionModule(QueryDefDLL, hInstance))
- return 0;
- new CDynLinkLibrary(QueryDefDLL);
- }
- else if (dwReason == DLL_PROCESS_DETACH)
- {
- TRACE0("QUERYDEF.DLL Terminating!n");
- AfxTermExtensionModule(QueryDefDLL);
- }
- return 1;
- }
- namespace QueryDef // use using namespace QueryDef or
- { // better USE_QUERYDEF macro
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // CQueryVariant Class
- //
- /*
- template <> void AFXAPI ConstructElements <QueryDef::CQueryVar>(QueryDef::CQueryVar* pNewQueryVar,int nCount)
- {
- #if defined(_DEBUG)
- #undef new
- #endif
- for ( int i = 0; i < nCount; i++, pNewQueryVar++ )
- // call CQueryVar default constructor directly
- new (pNewQueryVar) QueryDef::CQueryVar;
- }
- */
- void CQueryVariant::ConstructObject()
- {
- m_decPlaces = 2; // two decimal digits by default
- m_dateFormat = "%d/%m/%Y %H:%M"; // default date time format
- }
- CQueryVariant::CQueryVariant()
- {
- ConstructObject();
- m_varDB.Add(CQueryVar());
- }
- CQueryVariant::~CQueryVariant()
- {
- }
- CQueryVariant::CQueryVariant(LPCTSTR str)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(str));
- }
- CQueryVariant::CQueryVariant(int i)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(i));
- }
- CQueryVariant::CQueryVariant(long l)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(l));
- }
- CQueryVariant::CQueryVariant(short s)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(s));
- }
- CQueryVariant::CQueryVariant(float f)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(f));
- }
- CQueryVariant::CQueryVariant(double d)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(d));
- }
- CQueryVariant::CQueryVariant(COleDateTime& t)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(t));
- }
- CQueryVariant::CQueryVariant(CLongBinary& lB)
- {
- ConstructObject();
- m_varDB.Add(CQueryVar(lB));
- }
- // CQueryVariant conversion operators
- CQueryVariant::operator CString()
- {
- return (CString)(m_varDB[0]);
- }
- CQueryVariant::operator BYTE()
- {
- return (BYTE)(m_varDB[0]);
- }
- CQueryVariant::operator int()
- {
- return (int)(m_varDB[0]);
- }
- CQueryVariant::operator long()
- {
- return (long)(m_varDB[0]);
- }
- CQueryVariant::operator short()
- {
- return (short)(m_varDB[0]);
- }
- CQueryVariant::operator float()
- {
- return (float)(m_varDB[0]);
- }
- CQueryVariant::operator double()
- {
- return (double)(m_varDB[0]);
- }
- CQueryVariant::operator COleDateTime&()
- {
- return m_varDB[0].operator COleDateTime&();
- }
- CQueryVariant::operator CLongBinary&()
- {
- return (CLongBinary&)(m_varDB[0]);
- }
- CQueryVariant::operator LPCTSTR()
- {
- return (LPCTSTR)m_varDB[0];
- }
- CQueryVariant& CQueryVariant::operator=(CStringArray& src) // converts all columns to strings
- {
- src.SetSize(m_varDB.GetSize()); // make the two arrays equal length
- for (WORD i = 0; i < m_varDB.GetSize(); i++)
- src[i] = m_varDB.GetAt(i);
- return *this;
- }
- CQueryVar& CQueryVariant::operator[](int i)
- {
- if (i >= m_varDB.GetSize())
- SetSize(i+1);
- return m_varDB.ElementAt(i);
- }
- CQueryVariant& CQueryVariant::operator=(CQueryVariant& v)
- {
- m_decPlaces = v.m_decPlaces;
- m_dateFormat = v.m_dateFormat;
- m_varDB.SetSize(v.m_varDB.GetSize());
- for (WORD i = 0; i < m_varDB.GetSize(); i++)
- m_varDB[i] = v.m_varDB[i];
- return *this;
- }
- short CQueryVariant::SetDecimalDigits(short d)
- {
- short prevDecPlaces = m_decPlaces;
- m_decPlaces = d;
- for (WORD i = 0; i < m_varDB.GetSize(); i++)
- m_varDB[i].SetDecimalDigits(d);
- return prevDecPlaces;
- }
- LPCSTR CQueryVariant::SetDateFormat(LPCSTR strDateFormat)
- {
- CString oldDateFormat = m_dateFormat;
- m_dateFormat = strDateFormat;
- for (WORD i = 0; i < m_varDB.GetSize(); i++)
- m_varDB[i].SetDateFormat(strDateFormat);
- return oldDateFormat;
- }
- void CQueryVariant::SetSize(int nNewSize)
- {
- int i,nOldSize = m_varDB.GetSize();
- m_varDB.SetSize(nNewSize); // calls the CQueryVar constructor
- for (i = nOldSize; i < nNewSize; i++)
- {
- m_varDB[i].m_decPlaces = m_decPlaces;
- m_varDB[i].m_dateFormat = m_dateFormat;
- }
- }
- //////////////////////////////////////////////////////////////////////
- // CQueryVar Class
- //////////////////////////////////////////////////////////////////////
- void CQueryVar::ConstructObject()
- {
- m_decPlaces = 2; // two decimal digits by default
- m_dateFormat = "%d/%m/%Y %H:%M"; // default date time format
- m_allocFlags = eAllocNothing;
- }
- CQueryVar::CQueryVar()
- {
- ConstructObject();
- m_dwType = DBVT_NULL;
- }
- CQueryVar::~CQueryVar()
- { // may be marked as NULL but with
- if (m_dwType != DBVT_NULL) // buffers allocated due to a
- return; // AddNew or Edit applied on a
- // subsequent CQueryDef container
- if (m_allocFlags == eAllocString)
- delete m_pstring;
- else if (m_allocFlags == eAllocDate)
- delete m_pdate;
- else if (m_allocFlags == eAllocBinary)
- delete m_pbinary;
- }
- CQueryVar::CQueryVar(LPCTSTR str)
- {
- ConstructObject();
- m_pstring = new CString();
- *m_pstring = str;
- m_allocFlags = eAllocString;
- m_dwType = DBVT_STRING;
- }
- CQueryVar::CQueryVar(int i)
- {
- ConstructObject();
- m_dwType = DBVT_LONG;
- m_lVal = i;
- }
- CQueryVar::CQueryVar(long l)
- {
- ConstructObject();
- m_lVal = l;
- m_dwType = DBVT_LONG;
- }
- CQueryVar::CQueryVar(short s)
- {
- ConstructObject();
- m_iVal = s;
- m_dwType = DBVT_SHORT;
- }
- CQueryVar::CQueryVar(float f)
- {
- ConstructObject();
- m_fltVal = f;
- m_dwType = DBVT_SINGLE;
- }
- CQueryVar::CQueryVar(double d)
- {
- ConstructObject();
- m_dblVal = d;
- m_dwType = DBVT_DOUBLE;
- }
- CQueryVar::CQueryVar(COleDateTime& t)
- {
- ConstructObject();
- m_pdate = new TIMESTAMP_STRUCT;
- m_allocFlags = eAllocDate;
- m_pdate->year = (SWORD)t.GetYear();
- m_pdate->month = t.GetMonth();
- m_pdate->day = t.GetDay();
- m_pdate->hour = t.GetHour();
- m_pdate->minute = t.GetMinute();
- m_pdate->second = t.GetSecond();
- m_pdate->fraction = 0;
- m_dwType = DBVT_DATE;
- }
- CQueryVar::CQueryVar(CLongBinary& lB)
- {
- void* pSrc;
- void* pDest;
- ConstructObject();
- m_pbinary = new CLongBinary;
- m_allocFlags = eAllocBinary;
- m_pbinary->m_hData = GlobalAlloc(GMEM_MOVEABLE,lB.m_dwDataLength);
- pSrc = GlobalLock(lB.m_hData);
- pDest = GlobalLock(m_pbinary->m_hData);
- memcpy(pDest,pSrc,lB.m_dwDataLength);
- GlobalUnlock(lB.m_hData);
- GlobalUnlock(m_pbinary->m_hData);
- m_pbinary->m_dwDataLength = lB.m_dwDataLength;
- m_dwType = DBVT_BINARY;
- }
- // CQueryVar changes data type
- void CQueryVar::ChangeDataType(int allocFlags)
- {
- if (allocFlags == m_allocFlags)
- return;
- switch (m_allocFlags)
- {
- case eAllocString:
- delete m_pstring;
- break;
- case eAllocDate:
- delete m_pdate;
- break;
- case eAllocBinary:
- delete m_pbinary;
- break;
- }
- switch (allocFlags)
- {
- case eAllocString:
- m_pstring = new CString;
- break;
- case eAllocDate:
- m_pdate = new TIMESTAMP_STRUCT;
- break;
- case eAllocBinary:
- m_pbinary = new CLongBinary;
- m_pbinary->m_dwDataLength = 0;
- break;
- }
- m_allocFlags = allocFlags;
- }
- // CQueryVar conversion operators
- CQueryVar::operator LPCTSTR()
- {
- return ToString();
- }
- LPCTSTR CQueryVar::ToString()
- {
- CString strFormat;
- COleDateTime d;
- void* pbinary;
- switch (m_dwType)
- {
- case DBVT_NULL:
- break;
- case DBVT_BOOL:
- m_convert = m_boolVal? '1' : '0';
- break;
- case DBVT_UCHAR:
- m_convert.Format("%c",m_chVal);
- break;
- case DBVT_SHORT:
- m_convert.Format("%d",m_iVal);
- break;
- case DBVT_LONG:
- m_convert.Format("%ld",m_lVal);
- break;
- case DBVT_SINGLE:
- strFormat.Format("%%.%df",m_decPlaces);
- m_convert.Format(strFormat,m_fltVal);
- break;
- case DBVT_DOUBLE:
- strFormat.Format("%%.%dlf",m_decPlaces);
- m_convert.Format(strFormat,m_dblVal);
- break;
- case DBVT_DATE:
- d = operator COleDateTime&();
- m_convert = d.Format(m_dateFormat);
- break;
- case DBVT_STRING:
- m_convert = *m_pstring;
- break;
- case DBVT_BINARY:
- if (m_pbinary->m_dwDataLength > MAX_SHORT) // the BLOB is converted if less
- throw CQueryVariant::eMemoryLimit;
- pbinary = GlobalLock(m_pbinary->m_hData);
- if (pbinary)
- {
- m_convert = ConvertToHex(pbinary,m_pbinary->m_dwDataLength);
- GlobalUnlock(m_pbinary->m_hData);
- }
- break;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_convert;
- }
- CQueryVar::operator BYTE()
- {
- switch (m_dwType)
- {
- case DBVT_UCHAR:
- return m_chVal;
- case DBVT_BOOL:
- return m_boolVal;
- case DBVT_SHORT:
- return (BYTE)m_iVal;
- case DBVT_LONG:
- return (BYTE)m_lVal;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_chVal;
- }
- CQueryVar::operator int()
- {
- switch (m_dwType)
- {
- case DBVT_UCHAR:
- return m_chVal;
- case DBVT_SHORT:
- return m_iVal;
- case DBVT_BOOL:
- return m_boolVal;
- case DBVT_LONG:
- return m_lVal;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_lVal;
- }
- CQueryVar::operator long()
- {
- switch (m_dwType)
- {
- case DBVT_LONG:
- return m_lVal;
- case DBVT_UCHAR:
- return m_chVal;
- case DBVT_SHORT:
- return m_iVal;
- case DBVT_BOOL:
- return m_boolVal;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_lVal;
- }
- CQueryVar::operator short()
- {
- switch (m_dwType)
- {
- case DBVT_UCHAR:
- return m_chVal;
- case DBVT_SHORT:
- return m_iVal;
- case DBVT_BOOL:
- return m_boolVal;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_iVal;
- }
- CQueryVar::operator float()
- {
- switch (m_dwType)
- {
- case DBVT_UCHAR:
- return m_chVal;
- case DBVT_SHORT:
- return m_iVal;
- case DBVT_BOOL:
- return (float)m_boolVal;
- case DBVT_SINGLE:
- return m_fltVal;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_fltVal;
- }
- CQueryVar::operator double()
- {
- switch (m_dwType)
- {
- case DBVT_LONG:
- return m_lVal;
- case DBVT_UCHAR:
- return m_chVal;
- case DBVT_SHORT:
- return m_iVal;
- case DBVT_BOOL:
- return m_boolVal;
- case DBVT_SINGLE:
- return m_fltVal;
- case DBVT_DOUBLE:
- return m_dblVal;
- default:
- throw CQueryVar::eConversionError;
- }
- return m_dblVal;
- }
- CQueryVar::operator void*()
- {
- switch (m_dwType)
- {
- case DBVT_NULL: // patching CQueryDef (AddNew and Edit)
- if (m_allocFlags == eAllocString)
- return (void*)m_pstring;
- else if (m_allocFlags == eAllocDate)
- return (void*)m_pdate;
- else if (m_allocFlags == eAllocBinary)
- return (void*)m_pbinary;
- break;
- case DBVT_BOOL:
- case DBVT_UCHAR:
- case DBVT_SHORT:
- case DBVT_LONG:
- case DBVT_SINGLE:
- case DBVT_DOUBLE:
- return (void*)&m_chVal;
- case DBVT_STRING:
- return (void*)m_pstring;
- case DBVT_DATE:
- return (void*)m_pdate;
- case DBVT_BINARY:
- return (void*)m_pbinary;
- }
- return (void*)&m_chVal;
- }
- CQueryVar::operator COleDateTime&()
- {
- static COleDateTime t;
- if (m_dwType != DBVT_DATE)
- throw CQueryVar::eConversionError;
- t.SetDateTime(m_pdate->year,m_pdate->month,m_pdate->day,m_pdate->hour,m_pdate->minute,m_pdate->second);
- return t;
- }
- CQueryVar::operator CLongBinary&()
- {
- if (m_dwType != DBVT_BINARY)
- throw CQueryVar::eConversionError;
- return *m_pbinary;
- }
- CQueryVar& CQueryVar::operator=(LPCTSTR str)
- {
- m_dwType = DBVT_STRING;
- ChangeDataType(eAllocString);
- *m_pstring = str;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(UCHAR ch)
- {
- m_dwType = DBVT_UCHAR;
- ChangeDataType(eAllocNothing);
- m_chVal = ch;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(int l)
- {
- m_dwType = DBVT_LONG;
- ChangeDataType(eAllocNothing);
- m_lVal = l;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(long l)
- {
- m_dwType = DBVT_LONG;
- ChangeDataType(eAllocNothing);
- m_lVal = l;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(short s)
- {
- m_dwType = DBVT_SHORT;
- ChangeDataType(eAllocNothing);
- m_iVal = s;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(float f)
- {
- m_dwType = DBVT_SINGLE;
- ChangeDataType(eAllocNothing);
- m_fltVal = f;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(double d)
- {
- m_dwType = DBVT_DOUBLE;
- ChangeDataType(eAllocNothing);
- m_dblVal = d;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(COleDateTime& date)
- {
- m_dwType = DBVT_DATE;
- ChangeDataType(eAllocDate);
- m_pdate->year = date.GetYear();
- m_pdate->month = date.GetMonth();
- m_pdate->day = date.GetDay();
- m_pdate->hour = date.GetHour();
- m_pdate->minute = date.GetMinute();
- m_pdate->second = date.GetSecond();
- m_pdate->fraction = 0;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(CLongBinary& lB)
- {
- void* pSrc;
- void* pDest;
- int allocFlags;
- m_dwType = DBVT_BINARY;
- allocFlags = m_allocFlags;
- ChangeDataType(eAllocBinary);
- if (allocFlags != eAllocBinary)
- m_pbinary->m_hData = GlobalAlloc(GMEM_MOVEABLE,lB.m_dwDataLength);
- else if (m_pbinary->m_dwDataLength != lB.m_dwDataLength)
- m_pbinary->m_hData = GlobalReAlloc(m_pbinary->m_hData,lB.m_dwDataLength,GMEM_MOVEABLE);
- pSrc = GlobalLock(lB.m_hData);
- pDest = GlobalLock(m_pbinary->m_hData);
- memcpy(pDest,pSrc,lB.m_dwDataLength);
- GlobalUnlock(lB.m_hData);
- GlobalUnlock(m_pbinary->m_hData);
- m_pbinary->m_dwDataLength = lB.m_dwDataLength;
- return *this;
- }
- CQueryVar& CQueryVar::operator=(CQueryVar& v)
- {
- void* pSrc;
- void* pDest;
- int allocFlags;
- m_decPlaces = v.m_decPlaces;
- m_dateFormat= v.m_dateFormat;
- m_dwType = v.m_dwType;
- switch (m_dwType)
- {
- case DBVT_DATE:
- ChangeDataType(eAllocDate);
- memcpy(m_pdate,v.m_pdate,sizeof(TIMESTAMP_STRUCT));
- break;
- case DBVT_STRING:
- ChangeDataType(eAllocString);
- *m_pstring = *v.m_pstring;
- break;
- case DBVT_BINARY:
- allocFlags = m_allocFlags;
- ChangeDataType(eAllocBinary);
- if (allocFlags != eAllocBinary)
- m_pbinary->m_hData = GlobalAlloc(GMEM_MOVEABLE,v.m_pbinary->m_dwDataLength);
- else if (m_pbinary->m_dwDataLength != v.m_pbinary->m_dwDataLength)
- m_pbinary->m_hData = GlobalReAlloc(m_pbinary->m_hData,v.m_pbinary->m_dwDataLength,GMEM_MOVEABLE);
- pSrc = GlobalLock(v.m_pbinary->m_hData);
- pDest = GlobalLock(m_pbinary->m_hData);
- memcpy(pDest,pSrc,v.m_pbinary->m_dwDataLength);
- GlobalUnlock(v.m_pbinary->m_hData);
- GlobalUnlock(m_pbinary->m_hData);
- m_pbinary->m_dwDataLength = v.m_pbinary->m_dwDataLength;
- break;
- case DBVT_NULL:
- ChangeDataType(eAllocNothing);
- break;
- default:
- ChangeDataType(eAllocNothing);
- m_boolVal = v.m_boolVal;
- m_chVal = v.m_chVal;
- m_iVal = v.m_iVal;
- m_lVal = v.m_lVal;
- m_fltVal = v.m_fltVal;
- m_dblVal = v.m_dblVal;
- break;
- }
- return *this;
- }
- BOOL CQueryVar::operator==(CSQLNull& sqlNull)
- {
- return m_dwType == (DWORD)sqlNull.SqlNull;
- }
- BOOL CQueryVar::operator!=(CSQLNull& sqlNull)
- {
- return m_dwType != (DWORD)sqlNull.SqlNull;
- }
- short CQueryVar::SetDecimalDigits(short d)
- {
- short prevDecPlaces = m_decPlaces;
- m_decPlaces = d;
- return prevDecPlaces;
- }
- LPCSTR CQueryVar::SetDateFormat(LPCSTR strDateFormat)
- {
- CString oldDateFormat = m_dateFormat;
- m_dateFormat = strDateFormat;
- return oldDateFormat;
- }
- //////////////////////////////////////////////////////////////////////
- // V2.0 CQueryCol Class
- //
- CQueryCol::CQueryCol()
- {
- m_pValue = NULL;
- m_pfldInfo = NULL;
- }
- CQueryCol::CQueryCol(CQueryVar& qv,CODBCFieldInfo& fi)
- {
- m_pValue = &qv;
- m_pfldInfo = &fi;
- }
- CQueryCol::~CQueryCol()
- {
- }
- //////////////////////////////////////////////////////////////////////
- // CQueryDef Class
- //////////////////////////////////////////////////////////////////////
- IMPLEMENT_DYNAMIC(CQueryDef, CRecordset2)
- CQueryDef::CQueryDef(CDatabase* pDB) : CRecordset2(pDB)
- {
- m_nParams = 0;
- m_nFields = 0;
- m_nOpenType = CRecordset::forwardOnly; // helps implementation of ReOpen()
- m_dwOptions = CRecordset::readOnly;
- m_nMode = eModeNoMode;
- }
- CQueryDef::CQueryDef(CDatabase* pDB,LPCSTR strSelect) : CRecordset2(pDB)
- {
- m_nParams = 0;
- m_nFields = 0;
- m_nMode = eModeNoMode;
- Open(forwardOnly,strSelect,readOnly|noDirtyFieldCheck|executeDirect);
- }
- CQueryDef::~CQueryDef()
- {
- Close();
- }
- BOOL CQueryDef::Open(UINT nOpenType,LPCTSTR lpszSQL,DWORD dwOptions)
- {
- CString m_query;
- int i,maxQL;
- BOOL b;
- m_nOpenType = nOpenType; // helps implementation of ReOpen()
- m_strSQL = lpszSQL;
- m_dwOptions = dwOptions;
- m_originalQuery = lpszSQL;
- if (m_originalQuery.GetLength() == 0)
- m_originalQuery = GetDefaultSQL();
- for (maxQL = m_originalQuery.GetLength(), i = 0; i < maxQL; i++)
- {
- m_query += m_originalQuery[i];
- if (m_originalQuery[i] == '?')
- {
- m_ioParam[m_nParams] = 0;
- if (i+1 < maxQL && CString("LFDIYCBTX").Find(m_originalQuery[i+1]) != -1)
- m_ioParam[m_nParams] = m_originalQuery[++i];
- m_nParams++;
- }
- }
- m_cParam.SetSize(m_nParams);
- FreezeAllEvents(); // avoid NotifyMove before NotifyOpen
- b = CRecordset2::Open(nOpenType,m_query,dwOptions);
- FreezeAllEvents(FALSE); // restore notifications
- // V2.0 SQL column descriptors
- for (i = 0; i < GetODBCFieldCount(); i++)
- m_columns.Add(CQueryCol(m_cLine[i],m_ODBCFieldInfo[i]));
- NotifySink(eNotifyOpen); // is gotta be open then
- if (!IsEOF())
- NotifySink(eNotifyMove); // followed by move on the first record
- return b;
- }
- void CQueryDef::Close()
- {
- NotifySink(eNotifyClose);
- CRecordset2::Close();
- m_nFields = 0;
- m_nParams = 0;
- m_columns.RemoveAll();
- ClearEventSinkList();
- }
- BOOL CQueryDef::ReOpen(CDatabase* pDB)
- {
- if (IsOpen())
- Close();
- m_pDatabase = pDB;
- return Open(m_nOpenType,m_strSQL,m_dwOptions);
- }
- void CQueryDef::PreBindFields()
- {
- if (m_nFields == 0) // fetch columns information
- {
- m_nFields = GetODBCFieldCount();
- m_ODBCFieldInfo.SetSize(m_nFields);
- for (WORD i = 0; i < m_nFields; i++)
- GetODBCFieldInfo(i,m_ODBCFieldInfo[i]);
- m_cLine.SetSize(m_nFields); // make room for columns values
- }
- AllocStatusArrays(); // may change in future versions of MFC
- }
- void CQueryDef::AddNew()
- {
- m_nMode = eModeAddNew; // signal BindFields that an AddNew is in progress
- CRecordset2::AddNew();
- NotifySink(eNotifyAddNew);
- }
- void CQueryDef::Edit()
- {
- m_nMode = eModeEdit;
- CRecordset2::Edit();
- NotifySink(eNotifyEdit);
- }
- BOOL CQueryDef::Update()
- {
- BOOL bResult = CRecordset2::Update();
- m_nMode = eModeNoMode;
- NotifySink(eNotifyUpdate);
- return bResult;
- }
- void CQueryDef::Delete()
- {
- CRecordset2::Delete();
- NotifySink(eNotifyDelete);
- }
- BOOL CQueryDef::Requery()
- {
- BOOL b = CRecordset2::Requery();
- NotifySink(eNotifyRequery);
- return b;
- }
- void CQueryDef::CancelUpdate()
- {
- CRecordset2::CancelUpdate();
- NotifySink(eNotifyCancelUpdate);
- }
- void CQueryDef::DoFieldExchange(CFieldExchange* pFX) // input/output parameters only
- {
- BindParams(pFX);
- BindFields(pFX);
- }
- void CQueryDef::BindParams(CFieldExchange* pFX) // cannot have SQL_NULL outparams
- {
- USES_RecordsetPatch;
- unsigned int i;
- ASSERT(m_cParam.m_varDB.GetSize() == (WORD)m_nParams);
- for (i = 0; i < m_nParams; i++)
- {
- pFX->SetFieldType(m_ioParam[i]==0? CFieldExchange::inputParam : CFieldExchange::inoutParam);
- switch (m_ioParam[i])
- {
- case 'L':
- m_cParam.m_varDB[i].m_dwType = DBVT_LONG;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- break;
- case 'I':
- m_cParam.m_varDB[i].m_dwType = DBVT_SHORT;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- break;
- case 'Y':
- m_cParam.m_varDB[i].m_dwType = DBVT_UCHAR;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- break;
- case 'B':
- m_cParam.m_varDB[i].m_dwType = DBVT_BOOL;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- break;
- case 'C':
- m_cParam.m_varDB[i].m_dwType = DBVT_STRING;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocString);
- break;
- case 'F':
- m_cParam.m_varDB[i].m_dwType = DBVT_SINGLE;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- break;
- case 'D':
- m_cParam.m_varDB[i].m_dwType = DBVT_DOUBLE;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- break;
- case 'T':
- m_cParam.m_varDB[i].m_dwType = DBVT_DATE;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocDate);
- break;
- case 'X':
- m_cParam.m_varDB[i].m_dwType = DBVT_BINARY;
- m_cParam.m_varDB[i].ChangeDataType(CQueryVar::eAllocBinary);
- break;
- }
- switch (m_cParam.m_varDB[i].m_dwType)
- {
- case DBVT_NULL:
- CRecordset2::SetParamNull(i);
- RFX_Bool(pFX,"",m_cParam.m_varDB[i].m_boolVal); // phony binding
- break;
- case DBVT_BOOL:
- RFX_Bool(pFX,"",m_cParam.m_varDB[i].m_boolVal);
- break;
- case DBVT_STRING:
- RFX_Text(pFX,"",*m_cParam.m_varDB[i].m_pstring);
- break;
- case DBVT_UCHAR:
- RFX_Byte(pFX,"",m_cParam.m_varDB[i].m_chVal);
- break;
- case DBVT_LONG:
- RFX_Long(pFX,"",m_cParam.m_varDB[i].m_lVal);
- break;
- case DBVT_SHORT:
- RFX_Int(pFX,"",(int&)m_cParam.m_varDB[i].m_iVal);
- break;
- case DBVT_SINGLE:
- RFX_Single(pFX,"",m_cParam.m_varDB[i].m_fltVal);
- break;
- case DBVT_DOUBLE:
- RFX_Double(pFX,"",m_cParam.m_varDB[i].m_dblVal);
- break;
- case DBVT_DATE:
- RFX_Date(pFX,"",*m_cParam.m_varDB[i].m_pdate);
- break;
- case DBVT_BINARY:
- RFX_LongBinary(pFX,"",*m_cParam.m_varDB[i].m_pbinary);
- break;
- }
- }
- }
- void CQueryDef::BindFields(CFieldExchange* pFX)
- {
- static BOOL bReentrant = FALSE;
- DWORD dwType;
- USES_RecordsetPatch;
- for (UINT i = 0; i < m_nFields; i++)
- {
- if (!bReentrant && m_nMode != eModeNoMode) // AddNew or Edit
- {
- bReentrant = TRUE;
- if (m_cLine.m_varDB[i].m_dwType == DBVT_NULL)
- CRecordset::SetFieldNull(m_cLine.m_varDB[i],TRUE);
- else
- CRecordset::SetFieldNull(m_cLine.m_varDB[i],FALSE);
- bReentrant = FALSE;
- }
- pFX->SetFieldType(CFieldExchange::outputColumn);
- switch (m_ODBCFieldInfo[i].m_nSQLType)
- {
- case SQL_DATE:
- case SQL_TIME:
- case SQL_TIMESTAMP:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocDate);
- RFX_Date(pFX,m_ODBCFieldInfo[i].m_strName,*m_cLine.m_varDB[i].m_pdate);
- dwType = DBVT_DATE;
- break;
- case SQL_NUMERIC:
- case SQL_DECIMAL:
- case SQL_BIGINT:
- case SQL_CHAR:
- case SQL_VARCHAR:
- case SQL_LONGVARCHAR:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocString);
- RFX_Text(pFX,m_ODBCFieldInfo[i].m_strName,*m_cLine.m_varDB[i].m_pstring);
- dwType = DBVT_STRING;
- break;
- case SQL_BINARY:
- case SQL_VARBINARY:
- case SQL_LONGVARBINARY:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocBinary);
- RFX_LongBinary(pFX,m_ODBCFieldInfo[i].m_strName,*m_cLine.m_varDB[i].m_pbinary);
- dwType = DBVT_BINARY;
- break;
- case SQL_BIT:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- RFX_Bool(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_boolVal);
- dwType = DBVT_BOOL;
- break;
- case SQL_TINYINT:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- RFX_Byte(pFX,m_ODBCFieldInfo[i].m_strName,(BYTE&)m_cLine.m_varDB[i].m_iVal);
- dwType = DBVT_SHORT;
- break;
- case SQL_SMALLINT:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- RFX_Int(pFX,m_ODBCFieldInfo[i].m_strName,(int&)m_cLine.m_varDB[i].m_iVal);
- dwType = DBVT_SHORT;
- break;
- case SQL_INTEGER:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- RFX_Long(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_lVal);
- dwType = DBVT_LONG;
- break;
- case SQL_REAL:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- RFX_Single(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_fltVal);
- dwType = DBVT_SINGLE;
- break;
- case SQL_FLOAT:
- case SQL_DOUBLE:
- m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- RFX_Double(pFX,m_ODBCFieldInfo[i].m_strName,m_cLine.m_varDB[i].m_dblVal);
- dwType = DBVT_DOUBLE;
- break;
- }
- if (m_nMode == eModeNoMode)
- {
- m_cLine.m_varDB[i].m_dwType = dwType;
- if (IsFieldStatusNull(i))
- {
- // m_cLine.m_varDB[i].ChangeDataType(CQueryVar::eAllocNothing);
- m_cLine.m_varDB[i].m_dwType = DBVT_NULL;
- }
- }
- }
- }
- /* removed from V1.5 & later; has been replaced with RFX_xxx binding functions
- void CQueryDef::GetSQLData()
- {
- for (short i = 0; i < GetODBCFieldCount(); i++)
- {
- m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocNothing;
- GetFieldValue(i,m_cLine.m_varDB[i]);
- switch (m_ODBCFieldInfo[i].m_nSQLType)
- {
- case SQL_DATE:
- case SQL_TIME:
- case SQL_TIMESTAMP:
- m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocDate;
- break;
- case SQL_NUMERIC:
- case SQL_DECIMAL:
- case SQL_BIGINT:
- case SQL_CHAR:
- case SQL_VARCHAR:
- case SQL_LONGVARCHAR:
- m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocString;
- break;
- case SQL_BINARY:
- case SQL_VARBINARY:
- case SQL_LONGVARBINARY:
- m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocBinary;
- break;
- default:
- m_cLine.m_varDB[i].m_allocFlags = CQueryVar::eAllocNothing;
- break;
- }
- }
- }
- */
- CQueryVar& CQueryDef::operator[](int index)
- {
- return m_cLine[index];
- }
- CQueryVar& CQueryDef::operator[](LPCTSTR lpszColumnName) // applies only on columns
- {
- for (int i = 0; i < GetODBCFieldCount(); i++)
- if (m_ODBCFieldInfo[i].m_strName == lpszColumnName)
- return m_cLine[i];
- throw CQueryVar::eBoundary;
- return CQueryVar(); // never called
- }
- CQueryVariant& CQueryDef::operator=(CQueryVariant& v)
- {
- v.m_decPlaces = m_cLine.m_decPlaces;
- v.m_dateFormat = m_cLine.m_dateFormat;
- v.SetSize(m_cLine.Columns());
- for (WORD i = 0; i < v.Columns(); i++)
- v.m_varDB[i] = m_cLine.m_varDB[i];
- return v;
- }
- void CQueryDef::Move(long nRows,WORD wFetchType)
- {
- try
- {
- CRecordset::Move(nRows,wFetchType);
- }
- catch (CDBException* e) // no rowset; parameters only
- {
- if (e->m_strStateNativeOrigin.Left(11) != "State:24000") // invalid cursor state
- throw e;
- e->Delete();
- if (m_bEOF) // already been here
- return;
- m_bEOF = m_bBOF = TRUE;
- ASSERT_VALID(this);
- ASSERT(m_hstmt != SQL_NULL_HSTMT);
- CFieldExchange fx(CFieldExchange::Fixup,this); // fixup strings
- fx.m_hstmt = m_hstmt;
- DoFieldExchange(&fx);
- }
- NotifySink(eNotifyMove);
- // if (!IsEOF())
- // GetSQLData();
- }
- short CQueryDef::SetDecimalDigits(short d)
- {
- short s = m_cLine.SetDecimalDigits(d);
- NotifySink(eNotifyFormatChanged,eFormatChangedDecimalDigits);
- return s;
- }
- LPCSTR CQueryDef::SetDateFormat(LPCSTR strFormat)
- {
- LPCSTR lpstr = m_cLine.SetDateFormat(strFormat);
- NotifySink(eNotifyFormatChanged,eFormatChangedDate);
- return lpstr;
- }
- CQueryCol& CQueryDef::Column(LPCTSTR lpColName)
- {
- for (int i = 0; i < m_columns.GetSize(); i++)
- if (strcmp(m_columns[i].Name(),lpColName) == 0)
- return m_columns[i];
- throw CQueryVar::eBoundary;
- return CQueryCol(CQueryVar(),CODBCFieldInfo());
- }
- EVNHANDLE CQueryDef::Advise(IQueryDefEventSink* pSink)
- {
- return m_evSink.AddTail(new SQueryDefEventSink(pSink,FALSE));
- }
- void CQueryDef::Unadvise(EVNHANDLE evnHandle)
- {
- m_evSink.RemoveAt(evnHandle);
- }
- void CQueryDef::FreezeEvents(EVNHANDLE evnHandle,BOOL bFreeze)
- {
- m_evSink.GetAt(evnHandle)->m_frozen = bFreeze;
- }
- void CQueryDef::FreezeAllEvents(BOOL bFreeze)
- {
- // freeze all events keeping track of already frozen ones
- EVNHANDLE posHandle = m_evSink.GetHeadPosition();
- SQueryDefEventSink* pSink;
- int inc = bFreeze? +1 : -1;
- while (posHandle)
- {
- pSink = m_evSink.GetNext(posHandle);
- pSink->m_frozen += inc; // if 0 -> 1 if 1 -> 2 (all frozen)
- }
- }
- void CQueryDef::ClearEventSinkList()
- {
- EVNHANDLE evH = m_evSink.GetHeadPosition();
- while (evH != NULL)
- delete m_evSink.GetNext(evH);
- m_evSink.RemoveAll();
- }
- void CQueryDef::NotifySink(ENOTIFICATION nNotify,LPARAM lp)
- {
- SQueryDefEventSink* pSink;
- EVNHANDLE evnH = m_evSink.GetHeadPosition();
- EVNHANDLE evnHPrev;
- LPARAM retVal;
- while (evnH != NULL)
- {
- evnHPrev = evnH;
- pSink = m_evSink.GetNext(evnH);
- if (pSink->m_frozen)
- continue;
- // a sink returning non 0 value blocks all the other sinks receiving the notification
- switch (nNotify)
- {
- case eNotifyOpen:
- retVal = pSink->m_pSink->RSNotifyOpen(evnHPrev);
- break;
- case eNotifyClose:
- retVal = pSink->m_pSink->RSNotifyClose(evnHPrev);
- break;
- case eNotifyMove:
- retVal = pSink->m_pSink->RSNotifyMove(evnHPrev);
- break;
- case eNotifyAddNew:
- retVal = pSink->m_pSink->RSNotifyAddNew(evnHPrev);
- break;
- case eNotifyEdit:
- retVal = pSink->m_pSink->RSNotifyEdit(evnHPrev);
- break;
- case eNotifyUpdate:
- retVal = pSink->m_pSink->RSNotifyUpdate(evnHPrev);
- break;
- case eNotifyDelete:
- retVal = pSink->m_pSink->RSNotifyDelete(evnHPrev);
- break;
- case eNotifyCancelUpdate:
- retVal = pSink->m_pSink->RSNotifyCancelUpdate(evnHPrev);
- break;
- case eNotifyRequery:
- retVal = pSink->m_pSink->RSNotifyRequery(evnHPrev);
- break;
- case eNotifyFormatChanged:
- retVal = pSink->m_pSink->RSNotifyFormatChanged(evnHPrev,(BYTE)lp);
- break;
- default:
- break;
- }
- if (retVal != 0) // blocks event bubbling
- return;
- }
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // class CTabbedString
- //
- CTabbedString& CTabbedString::operator=(CQueryDef& qDef)
- {
- WORD nCount = qDef.GetODBCFieldCount();
- CQueryVar varTemp;
- Empty();
- for (WORD i = 0; i < nCount; i++)
- {
- varTemp = (CQueryVar&)qDef.m_cLine.m_varDB[i];
- if (!varTemp.IsNull())
- *this += (LPCTSTR)varTemp;
- else
- *this += "<NULL>";
- if (i+1 < nCount)
- *this += 't';
- }
- return *this;
- }
- CTabbedString& CTabbedString::operator=(CQueryVariant& qV)
- {
- WORD nCount = qV.Columns();
- CQueryVar varTemp;
- Empty();
- for (WORD i = 0; i < nCount; i++)
- {
- varTemp = (CQueryVar&)qV.m_varDB[i];
- if (!varTemp.IsNull())
- *this += (LPCTSTR)varTemp;
- else
- *this += "<NULL>";
- if (i+1 < nCount)
- *this += 't';
- }
- return *this;
- }
- CTabbedString CTabbedString::operator[](int index)
- {
- CString strRet;
- int nLength = GetLength();
- for (int i = 0; i < nLength; i++)
- {
- if (GetAt(i) == 't' && --index == 0)
- {
- i++;
- while (i < nLength && GetAt(i) != 't')
- strRet += GetAt(i++);
- }
- }
- if (index > -1)
- throw CQueryVariant::eBoundary;
- return strRet;
- }
- BOOL CTabbedString::IsNull(int index)
- {
- return operator[](index) == "<NULL>";
- }
- BOOL CTabbedString::operator==(CSQLNull&)
- {
- return *this == "<NULL>";
- }
- BOOL CTabbedString::operator!=(CSQLNull&)
- {
- return *this != "<NULL>";
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////
- // class CSQLNull
- //
- const int CSQLNull::SqlNull = DBVT_NULL; // taken from CDBVariant;
- BOOL CSQLNull::operator==(CQueryVar& qVar)
- {
- return SqlNull == qVar.m_dwType;
- }
- BOOL CSQLNull::operator!=(CQueryVar& qVar)
- {
- return SqlNull != qVar.m_dwType;
- }
- BOOL CSQLNull::operator==(CTabbedString& strTab)
- {
- return strTab == "<NULL>";
- }
- BOOL CSQLNull::operator!=(CTabbedString& strTab)
- {
- return strTab != "<NULL>";
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
- CString ConvertToHex(void* pbinary,int length) // converts a binary stream to hex representation
- {
- int i;
- char* p;
- CString s;
- BYTE b;
- for (i = 0, p = static_cast<char*>(pbinary); i < length; i++, p++)
- {
- b = *p & 0xF0;
- s += chHexDigits[b>>4];
- b = *p & 0x0F;
- s += chHexDigits[b];
- }
- s = (CString)"0x" + s;
- return s;
- }
- //////////////////////////////////////////////////////////////////////////////////////////////////////////////
- }; // namespace QueryDef
- #if defined(_QUERYDEFCOMPILE)
- __declspec(dllexport) QueryDef::CSQLNull SQL_NULL; // value of SQL NULL as defined by this class
- #endif