| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459 |
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #ifdef AFX_DB_SEG
- #pragma code_seg(AFX_DB_SEG)
- #endif
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- #define new DEBUG_NEW
- /////////////////////////////////////////////////////////////////////////////
- // CDBByteArray db specific class for holding byte array data
- class CDBByteArray : public CByteArray
- {
- DECLARE_DYNAMIC(CDBByteArray)
- // Operations
- void SetLength(int nNewSize);
- };
- inline void CDBByteArray::SetLength(int nNewSize)
- {
- // Can't grow buffer since ODBC has been SQLBindCol'd on it.
- ASSERT(nNewSize <= m_nMaxSize);
- m_nSize = nNewSize;
- }
- //////////////////////////////////////////////////////////////////////////////
- // CFieldExchange
- CFieldExchange::CFieldExchange(UINT nOperation, CRecordset* prs, void* pvField)
- {
- #ifdef _DEBUG
- ASSERT(nOperation >= BindParam && nOperation <= DumpField);
- #endif
- ASSERT_VALID(prs);
- ASSERT(prs->m_hstmt != SQL_NULL_HSTMT);
- m_nFieldType = (UINT) noFieldType;
- m_nOperation = nOperation;
- m_prs = prs;
- m_pvField = pvField;
- m_nFields = 0;
- m_nParams = 0;
- m_nParamFields = 0;
- m_bField = FALSE;
- m_pstr = NULL;
- m_hstmt = SQL_NULL_HSTMT;
- m_lDefaultLBFetchSize = 0x00010000;
- m_lDefaultLBReallocSize = 0x00010000;
- }
- BOOL CFieldExchange::IsFieldType(UINT* pnField)
- {
- if (m_nFieldType == outputColumn)
- {
- *pnField = ++m_nFields;
- // Recordset's m_nFields must match number of Fields!
- ASSERT(m_nFields <= m_prs->m_nFields);
- }
- else
- {
- // Make sure SetFieldType was called
- ASSERT(m_nFieldType == inputParam ||
- m_nFieldType == outputParam ||
- m_nFieldType == inoutParam);
- *pnField = ++m_nParams;
- // Recordset's m_nParams must match number of Params!
- ASSERT(m_nParams <= m_prs->m_nParams);
- }
- if (m_nOperation == BindParam || m_nOperation == RebindParam)
- {
- // only valid on a param field type
- return m_nFieldType != outputColumn;
- }
- else
- {
- // valid only on an outputColumn field type
- return m_nFieldType == outputColumn;
- }
- }
- // Default implementation for RFX functions
- void CFieldExchange::Default(LPCTSTR szName,
- void* pv, LONG* plLength, int nCType, UINT cbValue, UINT cbPrecision)
- {
- RETCODE nRetCode;
- UINT nField = (m_nFieldType == outputColumn)? m_nFields: m_nParams;
- switch (m_nOperation)
- {
- case BindParam:
- if (m_prs->IsParamStatusNull(nField - 1))
- *plLength = SQL_NULL_DATA;
- else
- *plLength = cbValue;
- // For params, CType is same as SQL type
- AFX_SQL_SYNC(::SQLBindParameter(m_hstmt, (UWORD)nField,
- (SWORD)m_nFieldType, (SWORD)nCType, (SWORD)nCType, cbPrecision, 0,
- pv, 0, plLength));
- if (nRetCode != SQL_SUCCESS)
- m_prs->ThrowDBException(nRetCode, m_hstmt);
- // Add the member address to the param map
- m_prs->m_mapParamIndex.SetAt(pv, (void*)nField);
- return;
- case RebindParam:
- // Only need to reset param length
- *plLength = m_prs->IsParamStatusNull(nField - 1) ? SQL_NULL_DATA : cbValue;
- return;
- case BindFieldForUpdate:
- if (!m_prs->IsFieldStatusDirty(nField - 1))
- {
- // If not dirty, set length to SQL_IGNORE for SQLSetPos updates
- *plLength = SQL_IGNORE;
- }
- else if (!m_prs->IsFieldStatusNull(nField - 1))
- {
- // Reset the length as it may have changed for var length fields
- *plLength = cbValue;
- }
- return;
- case UnbindFieldForUpdate:
- // Reset bound length to actual length to clear SQL_IGNOREs
- if (!m_prs->IsFieldStatusDirty(nField - 1))
- *plLength = cbValue;
- return;
- case BindFieldToColumn:
- AFX_SQL_SYNC(::SQLBindCol(m_prs->m_hstmt, (UWORD)nField, (SWORD)nCType,
- pv, cbValue, plLength));
- if (!m_prs->Check(nRetCode))
- m_prs->ThrowDBException(nRetCode);
- // Add the member address to the field map
- m_prs->m_mapFieldIndex.SetAt(pv, (void*)nField);
- return;
- case Name:
- if (m_prs->IsFieldStatusDirty(nField - 1))
- {
- // We require a name
- ASSERT(lstrlen(szName) != 0);
- *m_pstr += szName;
- *m_pstr += m_lpszSeparator;
- }
- return;
- case NameValue:
- if (m_prs->IsFieldStatusDirty(nField - 1))
- {
- *m_pstr += szName;
- *m_pstr += '=';
- }
- // Fall through
- case Value:
- if (m_prs->IsFieldStatusDirty(nField - 1))
- {
- // If user marked column NULL, reflect this in length
- if (m_prs->IsFieldStatusNull(nField - 1))
- *plLength = SQL_NULL_DATA;
- else
- *plLength = cbValue;
- // If optimizing for bulk add, only need lengths set correctly
- if(!(m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
- {
- *m_pstr += '?';
- *m_pstr += m_lpszSeparator;
- m_nParamFields++;
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &m_prs->m_rgODBCFieldInfos[nField - 1];
- AFX_SQL_SYNC(::SQLBindParameter(m_hstmt,
- (UWORD)m_nParamFields, SQL_PARAM_INPUT,
- (SWORD)nCType, pODBCInfo->m_nSQLType,
- pODBCInfo->m_nPrecision, pODBCInfo->m_nScale,
- pv, 0, plLength));
- if (nRetCode != SQL_SUCCESS)
- m_prs->ThrowDBException(nRetCode, m_hstmt);
- }
- }
- return;
- case MarkForUpdate:
- {
- // Get the field data
- CFieldInfo* pInfo = &m_prs->m_rgFieldInfos[nField - 1];
- // If user changed field value from previous value, mark field dirty
- if ((pInfo->m_bStatus & AFX_SQL_FIELD_FLAG_NULL))
- {
- if (!m_prs->IsFieldStatusNull(nField - 1))
- m_prs->SetDirtyFieldStatus(nField - 1);
- }
- else
- {
- // Saved field is not NULL. current field null, so field dirty
- BOOL bDirty = m_prs->IsFieldStatusNull(nField - 1);
- // If values differ, then field dirty
- void* pvDataCache;
- if (pInfo->m_nDataType == AFX_RFX_BOOL ||
- pInfo->m_nDataType == AFX_RFX_BYTE ||
- pInfo->m_nDataType == AFX_RFX_INT ||
- pInfo->m_nDataType == AFX_RFX_LONG ||
- pInfo->m_nDataType == AFX_RFX_SINGLE)
- {
- // If caching data by value, pass a ref
- pvDataCache = &pInfo->m_pvDataCache;
- }
- else
- pvDataCache = pInfo->m_pvDataCache;
- if (bDirty || !AfxCompareValueByRef(pv, pvDataCache, pInfo->m_nDataType))
- m_prs->SetDirtyFieldStatus(nField - 1);
- }
- #ifdef _DEBUG
- // Field address must not change - ODBC's SQLBindCol depends upon this
- void* pvBind;
- switch (pInfo->m_nDataType)
- {
- default:
- pvBind = pv;
- break;
- case AFX_RFX_LPTSTR:
- #ifdef _UNICODE
- pvBind = m_prs->m_pvFieldProxy[nField-1];
- #else // !_UNICODE
- pvBind = pv;
- #endif
- break;
- case AFX_RFX_TEXT:
- #ifdef _UNICODE
- pvBind = m_prs->m_pvFieldProxy[nField-1];
- #else // !_UNICODE
- {
- pvBind = ((CString*)pv)->GetBuffer(0);
- ((CString*)pv)->ReleaseBuffer();
- }
- #endif
- break;
- case AFX_RFX_OLEDATE:
- case AFX_RFX_DATE:
- pvBind = m_prs->m_pvFieldProxy[nField-1];
- break;
- case AFX_RFX_BINARY:
- pvBind = ((CByteArray*)pv)->GetData();
- break;
- }
- if (pInfo->m_pvBindAddress != pvBind)
- {
- TRACE1("Error: field address (column %u) has changed!\n",
- nField);
- ASSERT(FALSE);
- }
- #endif // _DEBUG
- if ((m_pvField == NULL || m_pvField == pv) &&
- m_prs->IsFieldStatusDirty(nField - 1))
- {
- m_bField = TRUE;
- }
- }
- return;
- case StoreField:
- AfxStoreField(*m_prs, nField, pv);
- return;
- case LoadField:
- AfxLoadField(*m_prs, nField, pv, plLength);
- return;
- default:
- ASSERT(FALSE);
- }
- }
- void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName,
- LPTSTR value, int nMaxLength, int nColumnType, short nScale)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- ASSERT(AfxIsValidAddress(value, nMaxLength));
- RETCODE nRetCode;
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- default:
- pFX->Default(szName, value, plLength,
- SQL_C_CHAR, lstrlen(value), nMaxLength);
- return;
- case CFieldExchange::BindParam:
- {
- void* pvParam = value; // will be overwritten if UNICODE
- #ifdef _UNICODE
- // Must use proxy to translate unicode data into non-unicode param
- pFX->m_prs->m_bRebindParams = TRUE;
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvParamProxy == NULL)
- {
- pFX->m_prs->m_pvParamProxy = new void*[pFX->m_prs->m_nParams];
- memset(pFX->m_prs->m_pvParamProxy, 0,
- pFX->m_prs->m_nParams*sizeof(void*));
- pFX->m_prs->m_nProxyParams = pFX->m_prs->m_nParams;
- }
- // Allocate non-unicode string to nMaxLength if necessary for SQLBindParameter
- if (pFX->m_prs->m_pvParamProxy[nField-1] == NULL)
- {
- pvParam = new CHAR[nMaxLength+1];
- pFX->m_prs->m_pvParamProxy[nField-1] = pvParam;
- }
- else
- pvParam = pFX->m_prs->m_pvParamProxy[nField-1];
- // Now fill in the data value
- USES_CONVERSION;
- lstrcpyA((char*)pvParam, T2A((LPCTSTR)value));
- #endif // _UNICODE
- *plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
- SQL_NULL_DATA : SQL_NTS;
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt, (UWORD)nField,
- (SWORD)pFX->m_nFieldType, SQL_C_CHAR, (SWORD)nColumnType,
- nMaxLength, nScale, pvParam, nMaxLength, plLength));
- if (nRetCode != SQL_SUCCESS)
- pFX->m_prs->ThrowDBException(nRetCode, pFX->m_hstmt);
- // Add the member address to the param map
- pFX->m_prs->m_mapParamIndex.SetAt(value, (void*)nField);
- }
- return;
- #ifdef _UNICODE
- case CFieldExchange::RebindParam:
- *plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
- SQL_NULL_DATA : SQL_NTS;
- if (pFX->m_prs->m_nProxyParams != 0)
- {
- // Fill buffer (expected by SQLBindParameter) with new param data
- USES_CONVERSION;
- LPSTR lpszParam = (LPSTR)pFX->m_prs->m_pvParamProxy[nField-1];
- lstrcpyA(lpszParam, T2A((LPCTSTR)value));
- }
- return;
- #endif // _UNICODE
- case CFieldExchange::BindFieldToColumn:
- {
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- UINT cbColumn = pODBCInfo->m_nPrecision;
- switch (pODBCInfo->m_nSQLType)
- {
- default:
- #ifdef _DEBUG
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: string converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- #endif // _DEBUG
- // Add room for extra information like sign, decimal point, etc.
- cbColumn += 10;
- break;
- case SQL_LONGVARCHAR:
- case SQL_CHAR:
- case SQL_VARCHAR:
- break;
- case SQL_FLOAT:
- case SQL_REAL:
- case SQL_DOUBLE:
- // Add room for sign, decimal point and " E +XXX"
- cbColumn += 10;
- break;
- case SQL_DECIMAL:
- case SQL_NUMERIC:
- // Add room for sign and decimal point
- cbColumn += 2;
- break;
- case SQL_TIMESTAMP:
- case SQL_DATE:
- case SQL_TIME:
- // May need extra space, i.e. "{TS mm/dd/yyyy hh:mm:ss}"
- cbColumn += 10;
- break;
- case SQL_TINYINT:
- case SQL_SMALLINT:
- case SQL_INTEGER:
- case SQL_BIGINT:
- // Add room for sign
- cbColumn += 1;
- break;
- }
- // Constrain to user specified max length, subject to 256 byte min
- if (cbColumn > (UINT)nMaxLength || cbColumn < 256)
- cbColumn = nMaxLength;
- // Set up binding addres
- void* pvData = value; // overwritten if _UNICODE
- value[cbColumn] = '\0';
- #ifdef _UNICODE
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvFieldProxy == NULL)
- {
- pFX->m_prs->m_pvFieldProxy = new void*[pFX->m_prs->m_nFields];
- memset(pFX->m_prs->m_pvFieldProxy, 0,
- pFX->m_prs->m_nFields*sizeof(void*));
- pFX->m_prs->m_nProxyFields = pFX->m_prs->m_nFields;
- }
- // Allocate non-unicode string for SQLBindCol (not necessary on Requery)
- if (pFX->m_prs->m_pvFieldProxy[nField-1] == NULL)
- pFX->m_prs->m_pvFieldProxy[nField-1] = new CHAR[cbColumn+2];
- pvData = pFX->m_prs->m_pvFieldProxy[nField-1];
- #endif // _UNICODE
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField,
- SQL_C_CHAR, pvData, cbColumn+1, plLength));
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- // Add the member address to the field map
- pFX->m_prs->m_mapFieldIndex.SetAt(value, (void*)nField);
- }
- return;
- #ifdef _UNICODE
- case CFieldExchange::BindFieldForUpdate:
- if (pFX->m_prs->m_nProxyFields != 0)
- {
- // Fill buffer (expected by SQLSetPos) with new field data
- USES_CONVERSION;
- LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- lstrcpyA(lpszData, T2A((LPCTSTR)value));
- pFX->Default(szName, (void *)lpszData, plLength, SQL_C_CHAR,
- lstrlenA(lpszData), nMaxLength);
- }
- return;
- #endif // _UNICODE
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value[0] = '\0';
- }
- else
- {
- #ifdef _UNICODE
- // Copy value out of the proxy
- value = (LPTSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- #endif
- LPTSTR lpsz = value;
- if (pFX->m_prs->m_pDatabase->m_bStripTrailingSpaces)
- {
- // find first trailing space
- LPTSTR lpszFirstTrailing = NULL;
- while (*lpsz != '\0')
- {
- if (*lpsz != ' ')
- lpszFirstTrailing = NULL;
- else
- {
- if (lpszFirstTrailing == NULL)
- lpszFirstTrailing = lpsz;
- }
- lpsz = _tcsinc(lpsz);
- }
- // truncate
- if (lpszFirstTrailing != NULL)
- *lpszFirstTrailing = '\0';
- }
- *plLength = lstrlen(value);
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- // Set string 0 length
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = SQL_NTS;
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- #ifdef _UNICODE
- case CFieldExchange::NameValue:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- *pFX->m_pstr += szName;
- *pFX->m_pstr += '=';
- }
- // Fall through
- case CFieldExchange::Value:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- // Get the field data
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- if (pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- USES_CONVERSION;
- lstrcpyA(lpszData, T2A((LPCTSTR)value));
- *plLength = lstrlen(value);
- }
- // If optimizing for bulk add, only need lengths & proxy set correctly
- if(!(pFX->m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
- {
- *pFX->m_pstr += '?';
- *pFX->m_pstr += pFX->m_lpszSeparator;
- pFX->m_nParamFields++;
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt,
- (UWORD)pFX->m_nParamFields, SQL_PARAM_INPUT,
- SQL_C_CHAR, pODBCInfo->m_nSQLType, nMaxLength,
- pODBCInfo->m_nScale, lpszData, 0, plLength));
- }
- }
- return;
- #endif // _UNICODE
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (*value != '\0')
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (*value == '\0')
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- else
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- pFX->Default(szName, value, plLength,
- SQL_C_CHAR, lstrlen(value), nMaxLength);
- return;
- case CFieldExchange::LoadField:
- {
- // Get the field data
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Restore the status
- pFX->m_prs->SetFieldStatus(nField - 1, pInfo->m_bStatus);
- // If not NULL, restore the value and length
- if (!pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- value = LPTSTR(pInfo->m_pvDataCache);
- *plLength = lstrlen(value);
- #ifdef _UNICODE
- // Must restore proxy for correct WHERE CURRENT OF operation
- USES_CONVERSION;
- LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- lstrcpyA(lpszData, T2A((LPCTSTR)value));
- #endif // _UNICODE
- }
- else
- {
- *plLength = SQL_NULL_DATA;
- }
- #ifdef _DEBUG
- // Buffer address must not change - ODBC's SQLBindCol depends upon this
- void* pvBind;
- #ifdef _UNICODE
- pvBind = pFX->m_prs->m_pvFieldProxy[nField-1];
- #else // !_UNICODE
- pvBind = value;
- #endif
- if (pvBind != pInfo->m_pvBindAddress)
- {
- TRACE1("Error: buffer (column %u) address has changed!\n",
- nField);
- ASSERT(FALSE);
- }
- #endif // _DEBUG
- }
- return;
- case CFieldExchange::StoreField:
- AfxStoreField(*pFX->m_prs, nField, value);
- return;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- pInfo->m_pvDataCache = new TCHAR[nMaxLength];
- pInfo->m_nDataType = AFX_RFX_LPTSTR;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- // Note: CString.m_pchData must not be changed. This address is registered
- // with ODBC and must remain valid until the recordset is released.
- void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName,
- CString& value, int nMaxLength, int nColumnType, short nScale)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- ASSERT(AfxIsValidAddress(&value, sizeof(CString)));
- RETCODE nRetCode;
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- default:
- pFX->Default(szName, value.GetBuffer(0), plLength,
- SQL_C_CHAR, value.GetLength(), nMaxLength);
- value.ReleaseBuffer();
- return;
- case CFieldExchange::BindParam:
- {
- // Preallocate to nMaxLength and setup binding address
- value.GetBufferSetLength(nMaxLength);
- void* pvParam = value.LockBuffer(); // will be overwritten if UNICODE
- #ifdef _UNICODE
- // Must use proxy to translate unicode data into non-unicode param
- pFX->m_prs->m_bRebindParams = TRUE;
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvParamProxy == NULL)
- {
- pFX->m_prs->m_pvParamProxy = new void*[pFX->m_prs->m_nParams];
- memset(pFX->m_prs->m_pvParamProxy, 0,
- pFX->m_prs->m_nParams*sizeof(void*));
- pFX->m_prs->m_nProxyParams = pFX->m_prs->m_nParams;
- }
- // Allocate non-unicode string to nMaxLength if necessary for SQLBindParameter
- if (pFX->m_prs->m_pvParamProxy[nField-1] == NULL)
- {
- pvParam = new CHAR[nMaxLength+1];
- pFX->m_prs->m_pvParamProxy[nField-1] = pvParam;
- }
- else
- pvParam = pFX->m_prs->m_pvParamProxy[nField-1];
- // Now fill in the data value
- USES_CONVERSION;
- lstrcpyA((char*)pvParam, T2A((LPCTSTR)value));
- #endif // _UNICODE
- *plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
- SQL_NULL_DATA : SQL_NTS;
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt, (UWORD)nField,
- (SWORD)pFX->m_nFieldType, SQL_C_CHAR, (SWORD)nColumnType,
- nMaxLength, nScale, pvParam, nMaxLength, plLength));
- value.ReleaseBuffer();
- if (nRetCode != SQL_SUCCESS)
- pFX->m_prs->ThrowDBException(nRetCode, pFX->m_hstmt);
- // Add the member address to the param map
- pFX->m_prs->m_mapParamIndex.SetAt(&value, (void*)nField);
- }
- return;
- #ifdef _UNICODE
- case CFieldExchange::RebindParam:
- *plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
- SQL_NULL_DATA : SQL_NTS;
- if (pFX->m_prs->m_nProxyParams != 0)
- {
- // Fill buffer (expected by SQLBindParameter) with new param data
- USES_CONVERSION;
- LPSTR lpszParam = (LPSTR)pFX->m_prs->m_pvParamProxy[nField-1];
- lstrcpyA(lpszParam, T2A((LPCTSTR)value));
- }
- return;
- #endif // _UNICODE
- case CFieldExchange::BindFieldToColumn:
- {
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- UINT cbColumn = pODBCInfo->m_nPrecision;
- switch (pODBCInfo->m_nSQLType)
- {
- default:
- #ifdef _DEBUG
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: CString converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- #endif // _DEBUG
- // Add room for extra information like sign, decimal point, etc.
- cbColumn += 10;
- break;
- case SQL_LONGVARCHAR:
- case SQL_CHAR:
- case SQL_VARCHAR:
- break;
- case SQL_FLOAT:
- case SQL_REAL:
- case SQL_DOUBLE:
- // Add room for sign, decimal point and " E +XXX"
- cbColumn += 10;
- break;
- case SQL_DECIMAL:
- case SQL_NUMERIC:
- // Add room for sign and decimal point
- cbColumn += 2;
- break;
- case SQL_TIMESTAMP:
- case SQL_DATE:
- case SQL_TIME:
- // May need extra space, i.e. "{TS mm/dd/yyyy hh:mm:ss}"
- cbColumn += 10;
- break;
- case SQL_TINYINT:
- case SQL_SMALLINT:
- case SQL_INTEGER:
- case SQL_BIGINT:
- // Add room for sign
- cbColumn += 1;
- break;
- }
- // Constrain to user specified max length, subject to 256 byte min
- if (cbColumn > (UINT)nMaxLength || cbColumn < 256)
- cbColumn = nMaxLength;
- // Set up binding addres
- void* pvData;
- value.GetBufferSetLength(cbColumn+1);
- pvData = value.LockBuffer(); // will be overwritten if UNICODE
- #ifdef _UNICODE
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvFieldProxy == NULL)
- {
- pFX->m_prs->m_pvFieldProxy = new void*[pFX->m_prs->m_nFields];
- memset(pFX->m_prs->m_pvFieldProxy, 0,
- pFX->m_prs->m_nFields*sizeof(void*));
- pFX->m_prs->m_nProxyFields = pFX->m_prs->m_nFields;
- }
- // Allocate non-unicode string for SQLBindCol (not necessary on Requery)
- if (pFX->m_prs->m_pvFieldProxy[nField-1] == NULL)
- pFX->m_prs->m_pvFieldProxy[nField-1] = new CHAR[cbColumn+2];
- pvData = pFX->m_prs->m_pvFieldProxy[nField-1];
- #endif // _UNICODE
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField,
- SQL_C_CHAR, pvData, cbColumn+1, plLength));
- value.ReleaseBuffer();
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- // Add the member address to the field map
- pFX->m_prs->m_mapFieldIndex.SetAt(&value, (void*)nField);
- }
- return;
- #ifdef _UNICODE
- case CFieldExchange::BindFieldForUpdate:
- if (pFX->m_prs->m_nProxyFields != 0)
- {
- // Fill buffer (expected by SQLSetPos) with new field data
- USES_CONVERSION;
- LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- lstrcpyA(lpszData, T2A((LPCTSTR)value));
- pFX->Default(szName, (void *)lpszData, plLength, SQL_C_CHAR,
- value.GetLength(), nMaxLength);
- }
- return;
- #endif // _UNICODE
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.GetBufferSetLength(0);
- value.ReleaseBuffer();
- }
- else
- {
- #ifdef _UNICODE
- // Copy value out of the proxy
- value = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- #endif
- LPTSTR lpsz = value.GetBuffer(0);
- if (pFX->m_prs->m_pDatabase->m_bStripTrailingSpaces)
- {
- // find first trailing space
- LPTSTR lpszFirstTrailing = NULL;
- while (*lpsz != '\0')
- {
- if (*lpsz != ' ')
- lpszFirstTrailing = NULL;
- else
- {
- if (lpszFirstTrailing == NULL)
- lpszFirstTrailing = lpsz;
- }
- lpsz = _tcsinc(lpsz);
- }
- // truncate
- if (lpszFirstTrailing != NULL)
- *lpszFirstTrailing = '\0';
- }
- value.ReleaseBuffer();
- *plLength = value.GetLength();
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- // Set string 0 length
- value.GetBufferSetLength(0);
- value.ReleaseBuffer();
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = SQL_NTS;
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- #ifdef _UNICODE
- case CFieldExchange::NameValue:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- *pFX->m_pstr += szName;
- *pFX->m_pstr += '=';
- }
- // Fall through
- case CFieldExchange::Value:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- // Get the field data
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- if (pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- USES_CONVERSION;
- lstrcpyA(lpszData, T2A((LPCTSTR)value));
- *plLength = value.GetLength();
- }
- // If optimizing for bulk add, only need lengths & proxy set correctly
- if(!(pFX->m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
- {
- *pFX->m_pstr += '?';
- *pFX->m_pstr += pFX->m_lpszSeparator;
- pFX->m_nParamFields++;
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt,
- (UWORD)pFX->m_nParamFields, SQL_PARAM_INPUT,
- SQL_C_CHAR, pODBCInfo->m_nSQLType, nMaxLength,
- pODBCInfo->m_nScale, lpszData, 0, plLength));
- }
- }
- return;
- #endif // _UNICODE
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (!value.IsEmpty())
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value.IsEmpty())
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- else
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- pFX->Default(szName, &value, plLength,
- SQL_C_CHAR, value.GetLength(), nMaxLength);
- return;
- case CFieldExchange::LoadField:
- {
- // Get the field data
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- CString* pStrCachedValue = (CString*)pInfo->m_pvDataCache;
- // Restore the status
- pFX->m_prs->SetFieldStatus(nField - 1, pInfo->m_bStatus);
- // If not NULL, restore the value and length
- if (!pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- value = *pStrCachedValue;
- *plLength = value.GetLength();
- #ifdef _UNICODE
- // Must restore proxy for correct WHERE CURRENT OF operation
- USES_CONVERSION;
- LPSTR lpszData = (LPSTR)pFX->m_prs->m_pvFieldProxy[nField-1];
- lstrcpyA(lpszData, T2A((LPCTSTR)value));
- #endif // _UNICODE
- }
- else
- {
- *plLength = SQL_NULL_DATA;
- }
- #ifdef _DEBUG
- // Buffer address must not change - ODBC's SQLBindCol depends upon this
- void* pvBind;
- #ifdef _UNICODE
- pvBind = pFX->m_prs->m_pvFieldProxy[nField-1];
- #else // !_UNICODE
- pvBind = value.GetBuffer(0);
- value.ReleaseBuffer();
- #endif
- if (pvBind != pInfo->m_pvBindAddress)
- {
- TRACE1("Error: CString buffer (column %u) address has changed!\n",
- nField);
- ASSERT(FALSE);
- }
- #endif // _DEBUG
- }
- return;
- case CFieldExchange::StoreField:
- AfxStoreField(*pFX->m_prs, nField, &value);
- return;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- pInfo->m_pvDataCache = new CString;
- pInfo->m_nDataType = AFX_RFX_TEXT;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Int(CFieldExchange* pFX, LPCTSTR szName, int& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_C_SHORT)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: int converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- }
- // fall through
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_C_LONG,
- sizeof(value), 5);
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_INT_PSEUDO_NULL;
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_INT_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(value);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (value != AFX_RFX_INT_PSEUDO_NULL)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value != AFX_RFX_INT_PSEUDO_NULL)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- goto LDefault;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Data cached by value, no allocation necessary
- pInfo->m_nDataType = AFX_RFX_INT;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Long(CFieldExchange* pFX, LPCTSTR szName, long& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_C_LONG)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: long converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- }
- // fall through
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_C_LONG,
- sizeof(value), 10);
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_LONG_PSEUDO_NULL;
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_LONG_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(value);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (value != AFX_RFX_LONG_PSEUDO_NULL)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value != AFX_RFX_LONG_PSEUDO_NULL)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- goto LDefault;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Data cached by value, no allocation necessary
- pInfo->m_nDataType = AFX_RFX_LONG;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Byte(CFieldExchange* pFX, LPCTSTR szName, BYTE& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_TINYINT)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: BYTE converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- }
- // fall through
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_TINYINT,
- sizeof(value), 3);
- break;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_BYTE_PSEUDO_NULL;
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_BYTE_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(value);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (value != AFX_RFX_BYTE_PSEUDO_NULL)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value != AFX_RFX_BYTE_PSEUDO_NULL)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- goto LDefault;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Data cached by value, no allocation necessary
- pInfo->m_nDataType = AFX_RFX_BYTE;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Bool(CFieldExchange* pFX, LPCTSTR szName, BOOL& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_BIT)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: BOOL converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- }
- // Fall through
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_BIT,
- sizeof(value), 1);
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_BOOL_PSEUDO_NULL;
- }
- else
- // Cast BYTE into BOOL (int)
- value = *(BYTE *)&value;
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_BOOL_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(value);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (value != AFX_RFX_BOOL_PSEUDO_NULL)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value != AFX_RFX_BOOL_PSEUDO_NULL)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- goto LDefault;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Data cached by value, no allocation necessary
- pInfo->m_nDataType = AFX_RFX_BOOL;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- // Note: CByteArray.m_pData must not be changed. This address is registered
- // with ODBC and must remain valid until the recordset is released.
- void AFXAPI RFX_Binary(CFieldExchange* pFX, LPCTSTR szName,
- CByteArray& value, int nMaxLength)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- RETCODE nRetCode;
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- BOOL bByRef = FALSE;
- switch (pFX->m_nOperation)
- {
- default:
- LDefault:
- {
- void* pvData = NULL;
- if (value.GetSize() > 0)
- {
- if (bByRef)
- pvData = &value;
- else
- pvData = &value[0];
- }
- pFX->Default(szName, pvData, plLength, SQL_C_BINARY,
- (int)value.GetSize(), (UINT)value.GetSize());
- }
- return;
- case CFieldExchange::BindFieldToColumn:
- {
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- UDWORD cbColumn = pODBCInfo->m_nPrecision;
- #ifdef _DEBUG
- if (pODBCInfo->m_nSQLType != SQL_BINARY &&
- pODBCInfo->m_nSQLType != SQL_VARBINARY &&
- pODBCInfo->m_nSQLType != SQL_LONGVARBINARY)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: CByteArray converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- // Constrain to user specified max length
- if (cbColumn > (UINT)nMaxLength)
- cbColumn = nMaxLength;
- value.SetSize(cbColumn);
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField,
- SQL_C_BINARY, &value[0], (LONG)cbColumn, plLength));
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- // Add the member address to the field map
- pFX->m_prs->m_mapFieldIndex.SetAt(&value, (void*)nField);
- }
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.SetSize(1);
- value[0] = AFX_RFX_BYTE_PSEUDO_NULL;
- }
- else
- {
- ASSERT(*plLength <= (LONG)nMaxLength);
- ((CDBByteArray&)value).SetLength((UINT)*plLength);
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.SetSize(1);
- value[0] = AFX_RFX_BYTE_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = value.GetSize();
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (value.GetSize() != 1 || value[0] != AFX_RFX_BYTE_PSEUDO_NULL)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value.GetSize() != 1 || value[0] != AFX_RFX_BYTE_PSEUDO_NULL)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- bByRef = TRUE;
- goto LDefault;
- case CFieldExchange::StoreField:
- AfxStoreField(*pFX->m_prs, nField, &value);
- return;
- case CFieldExchange::LoadField:
- AfxLoadField(*pFX->m_prs, nField, &value, plLength);
- return;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- pInfo->m_pvDataCache = new CByteArray;
- pInfo->m_nDataType = AFX_RFX_BINARY;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << ":";
- value.Dump(*pFX->m_pdcDump);
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, CTime& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- RETCODE nRetCode;
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_C_TIMESTAMP,
- sizeof(value), TIMESTAMP_PRECISION);
- return;
- case CFieldExchange::BindParam:
- {
- TIMESTAMP_STRUCT* pts;
- pFX->m_prs->m_bRebindParams = TRUE;
- if (pFX->m_prs->IsParamStatusNull(nField - 1))
- {
- pts = NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvParamProxy == NULL)
- {
- pFX->m_prs->m_pvParamProxy = new void*[pFX->m_prs->m_nParams];
- memset(pFX->m_prs->m_pvParamProxy, 0,
- pFX->m_prs->m_nParams*sizeof(void*));
- pFX->m_prs->m_nProxyParams = pFX->m_prs->m_nParams;
- }
- // Allocate TIMESTAMP_STRUCT if necessary for SQLBindParameter
- if (pFX->m_prs->m_pvParamProxy[nField-1] == NULL)
- {
- pts = new TIMESTAMP_STRUCT;
- pFX->m_prs->m_pvParamProxy[nField-1] = pts;
- }
- else
- pts = (TIMESTAMP_STRUCT *)pFX->m_prs->m_pvParamProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt, (UWORD)nField,
- (SWORD)pFX->m_nFieldType, SQL_C_TIMESTAMP, SQL_C_TIMESTAMP,
- TIMESTAMP_PRECISION, 0, pts, 0, plLength));
- if (nRetCode != SQL_SUCCESS)
- pFX->m_prs->ThrowDBException(nRetCode, pFX->m_hstmt);
- // Add the member address to the param map
- pFX->m_prs->m_mapParamIndex.SetAt(&value, (void*)nField);
- }
- return;
- case CFieldExchange::RebindParam:
- {
- *plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
- SQL_NULL_DATA : sizeof(TIMESTAMP_STRUCT);
- if (pFX->m_prs->m_nProxyParams != 0)
- {
- // Fill buffer (expected by SQLBindParameter) with new param data
- TIMESTAMP_STRUCT* pts;
- pts = (TIMESTAMP_STRUCT *)pFX->m_prs->m_pvParamProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- }
- }
- return;
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_DATE &&
- pODBCInfo->m_nSQLType != SQL_TIME &&
- pODBCInfo->m_nSQLType != SQL_TIMESTAMP)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: CTime converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvFieldProxy == NULL)
- {
- pFX->m_prs->m_pvFieldProxy = new void*[pFX->m_prs->m_nFields];
- memset(pFX->m_prs->m_pvFieldProxy, 0,
- pFX->m_prs->m_nFields*sizeof(void*));
- pFX->m_prs->m_nProxyFields = pFX->m_prs->m_nFields;
- }
- // Allocate TIMESTAMP_STRUCT for SQLBindCol (not necessary on Requery)
- if (pFX->m_prs->m_pvFieldProxy[nField-1] == NULL)
- pFX->m_prs->m_pvFieldProxy[nField-1] = new TIMESTAMP_STRUCT;
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField,
- SQL_C_TIMESTAMP, pFX->m_prs->m_pvFieldProxy[nField-1],
- sizeof(TIMESTAMP_STRUCT), plLength));
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- // Add the member address to the field map
- pFX->m_prs->m_mapFieldIndex.SetAt(&value, (void*)nField);
- }
- return;
- case CFieldExchange::BindFieldForUpdate:
- if (pFX->m_prs->m_nProxyFields != 0)
- {
- // Fill buffer (expected by SQLSetPos) with new field data
- TIMESTAMP_STRUCT* pts;
- pts = (TIMESTAMP_STRUCT *)pFX->m_prs->m_pvFieldProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- pFX->Default(szName, (void *)pts, plLength, SQL_C_TIMESTAMP,
- sizeof(TIMESTAMP_STRUCT), TIMESTAMP_PRECISION);
- }
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_DATE_PSEUDO_NULL;
- }
- else
- {
- TIMESTAMP_STRUCT* pts =
- (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
- if (pts->year < 1970 || pts->year > 2038)
- {
- // Time value out of range, return NULL
- #ifdef _DEBUG
- if (afxTraceFlags & traceDatabase)
- TRACE0("Warning: date value out of range, returning NULL value.\n");
- #endif
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_DATE_PSEUDO_NULL;
- }
- else
- {
- #ifdef _DEBUG
- if ((afxTraceFlags & traceDatabase) && pts->fraction != 0)
- TRACE0("Warning: ignoring milliseconds.\n");
- #endif
- value = CTime(pts->year, pts->month, pts->day,
- pts->hour, pts->minute, pts->second);
- }
- }
- return;
- case CFieldExchange::NameValue:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- *pFX->m_pstr += szName;
- *pFX->m_pstr += '=';
- }
- // Fall through
- case CFieldExchange::Value:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- TIMESTAMP_STRUCT* pts =
- (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
- if (pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- // If optimizing for bulk add, only need lengths & proxy set correctly
- if(!(pFX->m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
- {
- *pFX->m_pstr += '?';
- *pFX->m_pstr += pFX->m_lpszSeparator;
- pFX->m_nParamFields++;
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt,
- (UWORD)pFX->m_nParamFields, SQL_PARAM_INPUT,
- SQL_C_TIMESTAMP, pODBCInfo->m_nSQLType,
- TIMESTAMP_PRECISION, 0, pts, 0, plLength));
- }
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value = AFX_RFX_DATE_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- {
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- CTime timeNull = AFX_RFX_DATE_PSEUDO_NULL;
- if (value != timeNull)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- }
- return;
- case CFieldExchange::MarkForUpdate:
- {
- CTime timeNull = AFX_RFX_DATE_PSEUDO_NULL;
- if (value != timeNull)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- goto LDefault;
- case CFieldExchange::LoadField:
- {
- // Get the field data
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Restore the status
- pFX->m_prs->SetFieldStatus(nField - 1, pInfo->m_bStatus);
- // If not NULL, restore the value, length and proxy
- if (!pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- AfxCopyValueByRef(pInfo->m_pvDataCache, &value,
- plLength, pInfo->m_nDataType);
- // Restore proxy for correct WHERE CURRENT OF operations
- TIMESTAMP_STRUCT* pts =
- (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- }
- else
- *plLength = SQL_NULL_DATA;
- #ifdef _DEBUG
- // Buffer address must not change - ODBC's SQLBindCol depends upon this
- if (pInfo->m_pvBindAddress != pFX->m_prs->m_pvFieldProxy[nField-1])
- {
- TRACE1("Error: CString buffer (column %u) address has changed!\n",
- nField);
- ASSERT(FALSE);
- }
- #endif // _DEBUG
- }
- return;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- pInfo->m_pvDataCache = new CTime;
- pInfo->m_nDataType = AFX_RFX_DATE;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = " << value;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName,
- TIMESTAMP_STRUCT& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_DATE &&
- pODBCInfo->m_nSQLType != SQL_TIME &&
- pODBCInfo->m_nSQLType != SQL_TIMESTAMP)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: TIMESTAMP_STRUCT converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- // fall through
- }
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_C_TIMESTAMP,
- sizeof(value), TIMESTAMP_PRECISION);
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.year = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.month = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.day = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.hour = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.minute = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.second = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.fraction = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.year = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.month = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.day = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.hour = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.minute = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.second = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- value.fraction = AFX_RFX_TIMESTAMP_PSEUDO_NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (!(value.year == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.month == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.day == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.hour == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.minute == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.second == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.fraction == AFX_RFX_TIMESTAMP_PSEUDO_NULL ))
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (!(value.year == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.month == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.day == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.hour == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.minute == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.second == AFX_RFX_TIMESTAMP_PSEUDO_NULL &&
- value.fraction == AFX_RFX_TIMESTAMP_PSEUDO_NULL ))
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- goto LDefault;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- pInfo->m_pvDataCache = new TIMESTAMP_STRUCT;
- pInfo->m_nDataType = AFX_RFX_TIMESTAMP;
- }
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << ".year = " << (int)value.year;
- *pFX->m_pdcDump << "\n" << szName << ".month = " << value.month;
- *pFX->m_pdcDump << "\n" << szName << ".day = " << value.day;
- *pFX->m_pdcDump << "\n" << szName << ".hour = " << value.hour;
- *pFX->m_pdcDump << "\n" << szName << ".minute = " << value.minute;
- *pFX->m_pdcDump << "\n" << szName << ".second = " << value.second;
- *pFX->m_pdcDump << "\n" << szName << ".fraction = " << value.fraction;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName,
- COleDateTime& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- RETCODE nRetCode;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::BindParam:
- {
- TIMESTAMP_STRUCT* pts;
- pFX->m_prs->m_bRebindParams = TRUE;
- if (pFX->m_prs->IsParamStatusNull(nField - 1))
- {
- pts = NULL;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvParamProxy == NULL)
- {
- pFX->m_prs->m_pvParamProxy = new void*[pFX->m_prs->m_nParams];
- memset(pFX->m_prs->m_pvParamProxy, 0,
- pFX->m_prs->m_nParams*sizeof(void*));
- pFX->m_prs->m_nProxyParams = pFX->m_prs->m_nParams;
- }
- // Allocate TIMESTAMP_STRUCT if necessary for SQLBindParameter
- if (pFX->m_prs->m_pvParamProxy[nField-1] == NULL)
- {
- pts = new TIMESTAMP_STRUCT;
- pFX->m_prs->m_pvParamProxy[nField-1] = pts;
- }
- else
- pts = (TIMESTAMP_STRUCT *)pFX->m_prs->m_pvParamProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt, (UWORD)nField,
- (SWORD)pFX->m_nFieldType, SQL_C_TIMESTAMP, SQL_C_TIMESTAMP,
- TIMESTAMP_PRECISION, 0, pts, 0, plLength));
- if (nRetCode != SQL_SUCCESS)
- pFX->m_prs->ThrowDBException(nRetCode, pFX->m_hstmt);
- // Add the member address to the param map
- pFX->m_prs->m_mapParamIndex.SetAt(&value, (void*)nField);
- }
- return;
- case CFieldExchange::NameValue:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- *pFX->m_pstr += szName;
- *pFX->m_pstr += '=';
- }
- // Fall through
- case CFieldExchange::Value:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- TIMESTAMP_STRUCT* pts =
- (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
- if (pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- // If optimizing for bulk add, only need lengths & proxy set correctly
- if(!(pFX->m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
- {
- *pFX->m_pstr += '?';
- *pFX->m_pstr += pFX->m_lpszSeparator;
- pFX->m_nParamFields++;
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt,
- (UWORD)pFX->m_nParamFields, SQL_PARAM_INPUT,
- SQL_C_TIMESTAMP, pODBCInfo->m_nSQLType,
- TIMESTAMP_PRECISION, 0, pts, 0, plLength));
- }
- }
- return;
- case CFieldExchange::RebindParam:
- {
- *plLength = pFX->m_prs->IsParamStatusNull(nField - 1) ?
- SQL_NULL_DATA : sizeof(TIMESTAMP_STRUCT);
- if (pFX->m_prs->m_nProxyParams != 0)
- {
- // Fill buffer (expected by SQLBindParameter) with new param data
- TIMESTAMP_STRUCT* pts;
- pts = (TIMESTAMP_STRUCT *)pFX->m_prs->m_pvParamProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- }
- }
- return;
- case CFieldExchange::BindFieldForUpdate:
- if (pFX->m_prs->m_nProxyFields != 0)
- {
- // Fill buffer (expected by SQLSetPos) with new field data
- TIMESTAMP_STRUCT* pts;
- pts = (TIMESTAMP_STRUCT *)pFX->m_prs->m_pvFieldProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- pFX->Default(szName, (void *)pts, plLength, SQL_C_TIMESTAMP,
- sizeof(TIMESTAMP_STRUCT), TIMESTAMP_PRECISION);
- }
- return;
- case CFieldExchange::LoadField:
- {
- // Get the field data
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- // Restore the status
- pFX->m_prs->SetFieldStatus(nField - 1, pInfo->m_bStatus);
- // If not NULL, restore the value, length and proxy
- if (!pFX->m_prs->IsFieldStatusNull(nField - 1))
- {
- AfxCopyValueByRef(pInfo->m_pvDataCache, &value,
- plLength, pInfo->m_nDataType);
- // Restore proxy for correct WHERE CURRENT OF operations
- TIMESTAMP_STRUCT* pts =
- (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
- pts->year = (SWORD)value.GetYear();
- pts->month = (UWORD)value.GetMonth();
- pts->day = (UWORD)value.GetDay();
- pts->hour = (UWORD)value.GetHour();
- pts->minute = (UWORD)value.GetMinute();
- pts->second = (UWORD)value.GetSecond();
- pts->fraction = 0;
- }
- else
- *plLength = SQL_NULL_DATA;
- #ifdef _DEBUG
- // Buffer address must not change - ODBC's SQLBindCol depends upon this
- if (pInfo->m_pvBindAddress != pFX->m_prs->m_pvFieldProxy[nField-1])
- {
- TRACE1("Error: CString buffer (column %u) address has changed!\n",
- nField);
- ASSERT(FALSE);
- }
- #endif // _DEBUG
- }
- return;
- case CFieldExchange::BindFieldToColumn:
- {
- #ifdef _DEBUG
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- if (pODBCInfo->m_nSQLType != SQL_DATE &&
- pODBCInfo->m_nSQLType != SQL_TIME &&
- pODBCInfo->m_nSQLType != SQL_TIMESTAMP)
- {
- // Warn of possible field schema mismatch
- if (afxTraceFlags & traceDatabase)
- TRACE1("Warning: COleDateTime converted from SQL type %ld.\n",
- pODBCInfo->m_nSQLType);
- }
- #endif // _DEBUG
- // Allocate proxy array if necessary
- if (pFX->m_prs->m_pvFieldProxy == NULL)
- {
- pFX->m_prs->m_pvFieldProxy = new void*[pFX->m_prs->m_nFields];
- memset(pFX->m_prs->m_pvFieldProxy, 0,
- pFX->m_prs->m_nFields*sizeof(void*));
- pFX->m_prs->m_nProxyFields = pFX->m_prs->m_nFields;
- }
- // Allocate TIMESTAMP_STRUCT for SQLBindCol (not necessary on Requery)
- if (pFX->m_prs->m_pvFieldProxy[nField-1] == NULL)
- pFX->m_prs->m_pvFieldProxy[nField-1] = new TIMESTAMP_STRUCT;
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField,
- SQL_C_TIMESTAMP, pFX->m_prs->m_pvFieldProxy[nField-1],
- sizeof(TIMESTAMP_STRUCT), plLength));
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- // Add the member address to the field map
- pFX->m_prs->m_mapFieldIndex.SetAt(&value, (void*)nField);
- }
- return;
- default:
- LDefault:
- pFX->Default(szName, &value, plLength, SQL_C_TIMESTAMP,
- sizeof(value), TIMESTAMP_PRECISION);
- return;
- case CFieldExchange::AllocCache:
- {
- CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1];
- pInfo->m_pvDataCache = new COleDateTime;
- pInfo->m_nDataType = AFX_RFX_OLEDATE;
- }
- return;
- case CFieldExchange::Fixup:
- if (*plLength == SQL_NULL_DATA)
- {
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.SetStatus(COleDateTime::null);
- }
- else
- {
- TIMESTAMP_STRUCT* pts =
- (TIMESTAMP_STRUCT*)pFX->m_prs->m_pvFieldProxy[nField-1];
- #ifdef _DEBUG
- if ((afxTraceFlags & traceDatabase) && pts->fraction != 0)
- TRACE0("Warning: ignoring milliseconds.\n");
- #endif
- value = COleDateTime(pts->year, pts->month, pts->day,
- pts->hour, pts->minute, pts->second);
- }
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.SetStatus(COleDateTime::null);
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::MarkForAddNew:
- // can force writing of psuedo-null value (as a non-null) by setting field dirty
- if (value.GetStatus() != COleDateTime::null)
- {
- pFX->m_prs->SetDirtyFieldStatus(nField - 1);
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::MarkForUpdate:
- if (value.GetStatus() != COleDateTime::null)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- goto LDefault;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- CString str;
- str = value.Format();
- *pFX->m_pdcDump << "\n" << str;
- return;
- #endif // _DEBUG
- }
- }
- void AFXAPI RFX_LongBinary(CFieldExchange* pFX, LPCTSTR szName,
- CLongBinary& value)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- RETCODE nRetCode;
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(
- nField - 1, pFX->m_nFieldType);
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::Name:
- pFX->m_prs->m_bLongBinaryColumns = TRUE;
- pFX->Default(szName, &value, plLength, SQL_C_DEFAULT, 0, 0);
- return;
- case CFieldExchange::BindFieldToColumn:
- // Don't bind if using update SQL, simply do SQLGetData on Fixup
- if (!pFX->m_prs->m_bUseUpdateSQL && pFX->m_prs->CanUpdate())
- {
- // Bind for updates with cb=0 now. Driver may not support post Execute or ExtendedFetch binding
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt, (UWORD)nField, SQL_C_DEFAULT,
- &value, 0, plLength));
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- }
- // Add the member address to the field map
- pFX->m_prs->m_mapFieldIndex.SetAt(&value, (void*)nField);
- return;
- #ifdef _DEBUG
- case CFieldExchange::BindParam:
- // CLongBinary parameters are not supported
- ASSERT(FALSE);
- case CFieldExchange::MarkForAddNew:
- case CFieldExchange::MarkForUpdate:
- // We do not archive LongBinary values
- case CFieldExchange::StoreField:
- case CFieldExchange::LoadField:
- // We do not archive LongBinary values
- #endif // _DEBUG
- default:
- return;
- case CFieldExchange::Fixup:
- // Get the size of the long binary field
- *plLength = pFX->GetLongBinarySize(nField);
- // Get the data if necessary
- if (*plLength != SQL_NULL_DATA)
- pFX->GetLongBinaryData(nField, value, plLength);
- // Set the status and length
- if (*plLength == SQL_NULL_DATA)
- {
- // Field NULL, set length and status
- value.m_dwDataLength = 0;
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- }
- else
- {
- // Field not NULL, clear the status (length already set)
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- }
- return;
- case CFieldExchange::NameValue:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- *pFX->m_pstr += szName;
- *pFX->m_pstr += '=';
- }
- // Fall through
- case CFieldExchange::Value:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- // If user marked column NULL, reflect this in length
- if (pFX->m_prs->IsFieldStatusNull(nField - 1))
- *plLength = SQL_NULL_DATA;
- else
- {
- // Indicate data will be sent after SQLExecute
- // Length is signed value, it's limited by LONG_MAX
- if (value.m_dwDataLength >
- (ULONG)(LONG_MAX - labs(SQL_LEN_DATA_AT_EXEC_OFFSET)))
- {
- ASSERT(FALSE);
- *plLength = LONG_MAX - labs(SQL_LEN_DATA_AT_EXEC_OFFSET);
- }
- else
- *plLength = value.m_dwDataLength;
- *plLength = SQL_LEN_DATA_AT_EXEC(*plLength);
- }
- // If optimizing for bulk add, only need lengths set correctly
- if(!(pFX->m_prs->m_dwOptions & CRecordset::optimizeBulkAdd))
- {
- *pFX->m_pstr += '?';
- *pFX->m_pstr += pFX->m_lpszSeparator;
- pFX->m_nParamFields++;
- // Assumes all bound fields BEFORE unbound fields
- CODBCFieldInfo* pODBCInfo =
- &pFX->m_prs->m_rgODBCFieldInfos[nField - 1];
- AFX_SQL_SYNC(::SQLBindParameter(pFX->m_hstmt,
- (UWORD)pFX->m_nParamFields, SQL_PARAM_INPUT,
- SQL_C_DEFAULT, pODBCInfo->m_nSQLType,
- value.m_dwDataLength, 0, &value, 0, plLength));
- if (nRetCode != SQL_SUCCESS)
- pFX->m_prs->ThrowDBException(nRetCode, pFX->m_hstmt);
- }
- }
- return;
- case CFieldExchange::BindFieldForUpdate:
- if (pFX->m_prs->IsFieldStatusDirty(nField - 1))
- {
- // If user marked column NULL, reflect this in length
- if (pFX->m_prs->IsFieldStatusNull(nField - 1))
- *plLength = SQL_NULL_DATA;
- else
- {
- // Length is signed value, it's limited by LONG_MAX
- if (value.m_dwDataLength >
- (ULONG)(LONG_MAX - labs(SQL_LEN_DATA_AT_EXEC_OFFSET)))
- {
- ASSERT(FALSE);
- *plLength = LONG_MAX - labs(SQL_LEN_DATA_AT_EXEC_OFFSET);
- }
- else
- *plLength = value.m_dwDataLength;
- *plLength = SQL_LEN_DATA_AT_EXEC(*plLength);
- }
- }
- else
- *plLength = SQL_IGNORE;
- return;
- case CFieldExchange::UnbindFieldForUpdate:
- *plLength = value.m_dwDataLength;
- return;
- case CFieldExchange::SetFieldNull:
- if ((pFX->m_pvField == NULL &&
- pFX->m_nFieldType == CFieldExchange::outputColumn) ||
- pFX->m_pvField == &value)
- {
- if (pFX->m_bField)
- {
- // Mark fields null
- pFX->m_prs->SetNullFieldStatus(nField - 1);
- value.m_dwDataLength = 0;
- *plLength = SQL_NULL_DATA;
- }
- else
- {
- pFX->m_prs->ClearNullFieldStatus(nField - 1);
- // Length is signed value, it's limited by LONG_MAX
- if (value.m_dwDataLength >
- (ULONG)(LONG_MAX - labs(SQL_LEN_DATA_AT_EXEC_OFFSET)))
- {
- ASSERT(FALSE);
- *plLength = LONG_MAX - labs(SQL_LEN_DATA_AT_EXEC_OFFSET);
- }
- else
- *plLength = value.m_dwDataLength;
- *plLength = SQL_LEN_DATA_AT_EXEC(*plLength);
- }
- #ifdef _DEBUG
- pFX->m_nFieldFound = nField;
- #endif
- }
- return;
- case CFieldExchange::AllocCache:
- // Caching not supported for long binary
- return;
- #ifdef _DEBUG
- case CFieldExchange::DumpField:
- *pFX->m_pdcDump << "\n" << szName << " = ";
- value.Dump(*pFX->m_pdcDump);
- return;
- #endif // _DEBUG
- }
- }
- long CFieldExchange::GetLongBinarySize(int nField)
- {
- RETCODE nRetCode;
- int nDummy;
- long lSize;
- // Give empty buffer to find size of entire LongBinary
- AFX_ODBC_CALL(::SQLGetData(m_prs->m_hstmt,
- (UWORD)nField, SQL_C_DEFAULT, &nDummy, 0, &lSize));
- switch (nRetCode)
- {
- case SQL_SUCCESS:
- break;
- case SQL_SUCCESS_WITH_INFO:
- #ifdef _DEBUG
- if (afxTraceFlags & traceDatabase)
- {
- CDBException* e = new CDBException(nRetCode);
- e->BuildErrorString(m_prs->m_pDatabase,
- m_prs->m_hstmt, FALSE);
- // Ignore data truncated messages
- if (e->m_strStateNativeOrigin.Find(_T("State:01004")) < 0)
- {
- TRACE0("Warning: ODBC Success With Info, ");
- e->TraceErrorMessage(e->m_strError);
- e->TraceErrorMessage(e->m_strStateNativeOrigin);
- }
- e->Delete();
- }
- #endif // _DEBUG
- break;
- default:
- m_prs->ThrowDBException(nRetCode);
- }
- return lSize;
- }
- void CFieldExchange::GetLongBinaryData(int nField, CLongBinary& lb,
- long* plSize)
- {
- RETCODE nRetCode;
- long lActualDataSize = 0;
- long lChunkDataSize;
- long lReallocSize;
- const BYTE* lpLongBinary;
- lb.m_dwDataLength = 0;
- // Determine initial chunk sizes
- if (*plSize == SQL_NO_TOTAL)
- {
- lChunkDataSize = m_lDefaultLBFetchSize;
- lReallocSize = m_lDefaultLBReallocSize;
- }
- else
- {
- lChunkDataSize = *plSize;
- lReallocSize = *plSize;
- }
- do
- {
- // Check if CLongBianary is big enough
- lpLongBinary = ReallocLongBinary(lb,
- (long)lb.m_dwDataLength + lChunkDataSize,
- (long)lb.m_dwDataLength + lReallocSize);
- // Adjust the pointer so that data added at end
- lpLongBinary += lb.m_dwDataLength;
- AFX_ODBC_CALL(::SQLGetData(m_prs->m_hstmt, (UWORD)nField,
- SQL_C_BINARY, (UCHAR*)lpLongBinary, lChunkDataSize, &lActualDataSize));
- ::GlobalUnlock(lb.m_hData);
- switch (nRetCode)
- {
- case SQL_NO_DATA_FOUND:
- m_prs->SetNullFieldStatus(nField - 1);
- *plSize = SQL_NULL_DATA;
- break;
- case SQL_SUCCESS:
- // All data fetched
- lb.m_dwDataLength += lActualDataSize;
- *plSize = (long)lb.m_dwDataLength;
- return;
- case SQL_SUCCESS_WITH_INFO:
- {
- CDBException* e = new CDBException(nRetCode);
- e->BuildErrorString(m_prs->m_pDatabase, m_prs->m_hstmt,
- FALSE);
- // Ignore data truncated messages
- if (e->m_strStateNativeOrigin.Find(_T("State:01004")) < 0)
- {
- #ifdef _DEBUG
- if (afxTraceFlags & traceDatabase)
- {
- TRACE0("Warning: ODBC Success With Info, ");
- e->TraceErrorMessage(e->m_strError);
- e->TraceErrorMessage(e->m_strStateNativeOrigin);
- }
- #endif // _DEBUG
- // Must be some other warning, should be finished
- lb.m_dwDataLength += lActualDataSize;
- }
- else
- {
- // Should only happen if further calls to SQLGetData necessary
- // Increment the length by the chunk size for subsequent SQLGetData call
- lb.m_dwDataLength += lChunkDataSize;
- // Recalculate chunk and alloc sizes
- lChunkDataSize = m_prs->GetLBFetchSize(lChunkDataSize);
- lReallocSize = m_prs->GetLBReallocSize(lReallocSize);
- // force loop to repeat
- lActualDataSize = SQL_NO_TOTAL;
- }
- *plSize = (long)lb.m_dwDataLength;
- e->Delete();
- }
- break;
- default:
- m_prs->ThrowDBException(nRetCode);
- }
- } while (lActualDataSize == SQL_NO_TOTAL);
- }
- BYTE* CFieldExchange::ReallocLongBinary(CLongBinary& lb, long lSizeRequired,
- long lReallocSize)
- {
- // realloc max of lSizeRequired, lReallocSize (m_dwDataLength untouched)
- if (lSizeRequired < 0)
- {
- ASSERT(FALSE);
- lSizeRequired = 0;
- }
- HGLOBAL hOldData = NULL;
- // Allocate or Realloc as req'd
- if (lb.m_hData == NULL)
- lb.m_hData = ::GlobalAlloc(GMEM_MOVEABLE, lReallocSize);
- else
- {
- DWORD dwSize = ::GlobalSize(lb.m_hData);
- if (dwSize < (DWORD)lSizeRequired)
- {
- // Save the old handle in case ReAlloc fails
- hOldData = lb.m_hData;
- // Allocate more memory if necessary
- lb.m_hData = ::GlobalReAlloc(lb.m_hData,
- __max(lSizeRequired, lReallocSize), GMEM_MOVEABLE);
- }
- }
- // Validate the memory was allocated and can be locked
- if (lb.m_hData == NULL)
- {
- // Restore the old handle (not NULL if Realloc failed)
- lb.m_hData = hOldData;
- AfxThrowMemoryException();
- }
- BYTE* lpLongBinary = (BYTE*)::GlobalLock(lb.m_hData);
- if (lpLongBinary == NULL)
- {
- ::GlobalFree(lb.m_hData);
- lb.m_hData = NULL;
- AfxThrowMemoryException();
- }
- return lpLongBinary;
- }
- //////////////////////////////////////////////////////////////////////////////
- // Recordset Field Exchange Helpers
- void AFXAPI AfxStoreField(CRecordset& rs, UINT nField, void* pvField)
- {
- // Get the field data
- CFieldInfo* pInfo = &rs.m_rgFieldInfos[nField - 1];
- // Cache the status
- pInfo->m_bStatus = rs.GetFieldStatus(nField - 1);
- // Save the data
- if (!rs.IsFieldStatusNull(nField - 1))
- {
- // Don't need to save length for variable len
- // objects as CString and CByteArray track len internally
- long nDummyLength;
- if (pInfo->m_nDataType == AFX_RFX_BOOL ||
- pInfo->m_nDataType == AFX_RFX_BYTE ||
- pInfo->m_nDataType == AFX_RFX_INT ||
- pInfo->m_nDataType == AFX_RFX_LONG ||
- pInfo->m_nDataType == AFX_RFX_SINGLE)
- {
- // If caching data by value, pass a ref
- AfxCopyValueByRef(pvField, &pInfo->m_pvDataCache,
- &nDummyLength, pInfo->m_nDataType);
- }
- else
- {
- AfxCopyValueByRef(pvField, pInfo->m_pvDataCache,
- &nDummyLength, pInfo->m_nDataType);
- }
- }
- #ifdef _DEBUG
- // Cache the bind address expected by ODBC
- switch(pInfo->m_nDataType)
- {
- default:
- // All types that are bound directly
- pInfo->m_pvBindAddress = pvField;
- break;
- case AFX_RFX_TEXT:
- #ifdef _UNICODE
- pInfo->m_pvBindAddress = rs.m_pvFieldProxy[nField-1];
- #else
- pInfo->m_pvBindAddress = ((CString*)pvField)->GetBuffer(0);
- ((CString*)pvField)->ReleaseBuffer();
- #endif
- break;
- case AFX_RFX_LPTSTR:
- #ifdef _UNICODE
- pInfo->m_pvBindAddress = rs.m_pvFieldProxy[nField-1];
- #else
- pInfo->m_pvBindAddress = pvField;
- #endif
- break;
- case AFX_RFX_DATE:
- case AFX_RFX_OLEDATE:
- pInfo->m_pvBindAddress = rs.m_pvFieldProxy[nField-1];
- break;
- case AFX_RFX_BINARY:
- pInfo->m_pvBindAddress = ((CByteArray*)pvField)->GetData();
- break;
- }
- #endif
- }
- void AFXAPI AfxLoadField(CRecordset& rs, UINT nField,
- void* pvField, long* plLength)
- {
- // Get the field data
- CFieldInfo* pInfo = &rs.m_rgFieldInfos[nField - 1];
- // Assumes old field status cleared out
- rs.SetFieldStatus(nField - 1, pInfo->m_bStatus);
- // If not NULL, restore the value and the length
- if (!rs.IsFieldStatusNull(nField - 1))
- {
- if (pInfo->m_nDataType == AFX_RFX_BOOL ||
- pInfo->m_nDataType == AFX_RFX_BYTE ||
- pInfo->m_nDataType == AFX_RFX_INT ||
- pInfo->m_nDataType == AFX_RFX_LONG ||
- pInfo->m_nDataType == AFX_RFX_SINGLE)
- {
- // If caching data by value, pass a ref
- AfxCopyValueByRef(&pInfo->m_pvDataCache, pvField,
- plLength, pInfo->m_nDataType);
- }
- else
- {
- AfxCopyValueByRef(pInfo->m_pvDataCache, pvField,
- plLength, pInfo->m_nDataType);
- }
- }
- else
- *plLength = SQL_NULL_DATA;
- #ifdef _DEBUG
- // Buffer address must not change - ODBC's SQLBindCol depends upon this
- if (pInfo->m_nDataType == AFX_RFX_BINARY)
- {
- // Change pvField to point to the data of the CByteArray
- pvField = ((CByteArray*)pvField)->GetData();
- }
- if (pInfo->m_pvBindAddress != pvField)
- {
- TRACE1("Error: field address (column %u) has changed!\n",
- nField);
- ASSERT(FALSE);
- }
- #endif // _DEBUG
- }
- BOOL AFXAPI AfxCompareValueByRef(void* pvSrc, void* pvDest, int nSrcType)
- {
- ASSERT(pvSrc != NULL);
- ASSERT(pvDest != NULL);
- BOOL bCompare = FALSE;
- switch(nSrcType)
- {
- case AFX_RFX_LONGBINARY:
- // Caching long binary Src not supported
- default:
- ASSERT(FALSE);
- break;
- case AFX_RFX_LPTSTR:
- if (lstrcmp((LPTSTR) pvDest, (LPTSTR) pvSrc) == 0)
- bCompare = TRUE;
- break;
- case AFX_RFX_TEXT:
- if (*(CString*)pvDest == *(CString*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_BINARY:
- {
- CByteArray* pByteArraySrc = (CByteArray*)pvSrc;
- CByteArray* pByteArrayDest = (CByteArray*)pvDest;
- // If sizes compare, compare the Src
- int nSize = pByteArraySrc->GetSize();
- if (nSize == pByteArrayDest->GetSize())
- {
- if (memcmp(&pByteArrayDest[0], &pByteArraySrc[0], nSize) == 0)
- bCompare = TRUE;
- }
- }
- break;
- case AFX_RFX_BOOL:
- if (*(BOOL*)pvDest == *(BOOL*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_BYTE:
- if (*(BYTE*)pvDest == *(BYTE*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_INT:
- if (*(int*)pvDest == *(int*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_LONG:
- if (*(long*)pvDest == *(long*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_SINGLE:
- if (*(float*)pvDest == *(float*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_DOUBLE:
- if (*(double*)pvDest == *(double*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_OLEDATE:
- if (*(COleDateTime*)pvDest == *(COleDateTime*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_DATE:
- if (*(CTime*)pvDest == *(CTime*)pvSrc)
- bCompare = TRUE;
- break;
- case AFX_RFX_TIMESTAMP:
- {
- TIMESTAMP_STRUCT* pSrc = (TIMESTAMP_STRUCT*)pvSrc;
- TIMESTAMP_STRUCT* pDest = (TIMESTAMP_STRUCT*)pvDest;
- if ((pSrc->year == pDest->year &&
- pSrc->month == pDest->month &&
- pSrc->day == pDest->day &&
- pSrc->hour == pDest->hour &&
- pSrc->minute == pDest->minute &&
- pSrc->second == pDest->second &&
- pSrc->fraction == pDest->fraction))
- {
- bCompare = TRUE;
- }
- }
- break;
- }
- return bCompare;
- }
- void AFXAPI AfxCopyValueByRef(void* pvSrc, void* pvDest, long* plLength, int nDestType)
- {
- ASSERT(pvSrc != NULL);
- ASSERT(pvDest != NULL);
- ASSERT(plLength != NULL);
- switch (nDestType)
- {
- case AFX_RFX_LONGBINARY:
- // Caching long binary Dest not supported
- default:
- ASSERT(FALSE);
- break;
- case AFX_RFX_LPTSTR:
- lstrcpy((LPTSTR) pvDest, (LPTSTR) pvSrc);
- *plLength = lstrlen((LPTSTR) pvDest);
- break;
- case AFX_RFX_TEXT:
- *(CString*)pvDest = *(CString*)pvSrc;
- *plLength = ((CString*)pvSrc)->GetLength();
- break;
- case AFX_RFX_BINARY:
- ((CByteArray*)pvDest)->Copy(*(CByteArray*)pvSrc);
- *plLength = ((CByteArray*)pvSrc)->GetSize();
- break;
- case AFX_RFX_BOOL:
- *(BOOL*)pvDest = *(BOOL*)pvSrc;
- *plLength = sizeof(BOOL);
- break;
- case AFX_RFX_BYTE:
- *(BYTE*)pvDest = *(BYTE*)pvSrc;
- *plLength = sizeof(BYTE);
- break;
- case AFX_RFX_INT:
- *(int*)pvDest = *(int*)pvSrc;
- *plLength = sizeof(int);
- break;
- case AFX_RFX_LONG:
- *(long*)pvDest = *(long*)pvSrc;
- *plLength = sizeof(long);
- break;
- case AFX_RFX_SINGLE:
- *(float*)pvDest = *(float*)pvSrc;
- *plLength = sizeof(float);
- break;
- case AFX_RFX_DOUBLE:
- *(double*)pvDest = *(double*)pvSrc;
- *plLength = sizeof(double);
- break;
- case AFX_RFX_DATE:
- *(CTime*)pvDest = *(CTime*)pvSrc;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- break;
- case AFX_RFX_OLEDATE:
- *(COleDateTime*)pvDest = *(COleDateTime*)pvSrc;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- break;
- case AFX_RFX_TIMESTAMP:
- {
- TIMESTAMP_STRUCT* pDest = (TIMESTAMP_STRUCT*)pvDest;
- TIMESTAMP_STRUCT* pSrc = (TIMESTAMP_STRUCT*)pvSrc;
- pDest->year = pSrc->year;
- pDest->month = pSrc->month;
- pDest->day = pSrc->day;
- pDest->hour = pSrc->hour;
- pDest->minute = pSrc->minute;
- pDest->second = pSrc->second;
- pDest->fraction = pSrc->fraction;
- *plLength = sizeof(TIMESTAMP_STRUCT);
- }
- break;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // Bulk Recordset Field Exchange
- void AFXAPI RFX_Text_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- LPSTR* prgStrVals, long** prgLengths, int nMaxLength)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgStrVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgStrVals = new char[nRowsetSize * nMaxLength];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgStrVals;
- *prgStrVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgStrVals, *prgLengths,
- SQL_C_CHAR, nMaxLength);
- break;
- }
- }
- void AFXAPI RFX_Bool_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- BOOL** prgBoolVals, long** prgLengths)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgBoolVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgBoolVals = new BOOL[nRowsetSize];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgBoolVals;
- *prgBoolVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgBoolVals, *prgLengths,
- SQL_C_LONG, sizeof(BOOL));
- break;
- }
- }
- void AFXAPI RFX_Int_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- int** prgIntVals, long** prgLengths)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgIntVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgIntVals = new int[nRowsetSize];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgIntVals;
- *prgIntVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgIntVals, *prgLengths,
- SQL_C_LONG, sizeof(int));
- break;
- }
- }
- void AFXAPI RFX_Long_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- long** prgLongVals, long** prgLengths)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgLongVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgLongVals = new long[nRowsetSize];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgLongVals;
- *prgLongVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgLongVals, *prgLengths,
- SQL_C_LONG, sizeof(long));
- break;
- }
- }
- void AFXAPI RFX_Date_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- TIMESTAMP_STRUCT** prgTSVals, long** prgLengths)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgTSVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgTSVals = new TIMESTAMP_STRUCT[nRowsetSize];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgTSVals;
- *prgTSVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgTSVals, *prgLengths,
- SQL_C_TIMESTAMP, sizeof(TIMESTAMP_STRUCT));
- break;
- }
- }
- void AFXAPI RFX_Byte_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- BYTE** prgByteVals, long** prgLengths)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgByteVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgByteVals = new BYTE[nRowsetSize];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgByteVals;
- *prgByteVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgByteVals, *prgLengths,
- SQL_C_TINYINT, sizeof(BYTE));
- break;
- }
- }
- void AFXAPI RFX_Binary_Bulk(CFieldExchange* pFX, LPCTSTR szName,
- BYTE** prgByteVals, long** prgLengths, int nMaxLength)
- {
- ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange)));
- ASSERT(AfxIsValidString(szName));
- UINT nField;
- if (!pFX->IsFieldType(&nField))
- return;
- switch (pFX->m_nOperation)
- {
- case CFieldExchange::AllocMultiRowBuffer:
- {
- // The buffer pointer better be initialized to NULL
- // or cleanup in exceptional cases mail fail
- ASSERT(*prgByteVals == NULL);
- ASSERT(*prgLengths == NULL);
- int nRowsetSize = pFX->m_prs->GetRowsetSize();
- // Allocate buffers to hold data and length
- *prgByteVals = new BYTE[nRowsetSize * nMaxLength];
- *prgLengths = new long[nRowsetSize];
- }
- break;
- case CFieldExchange::DeleteMultiRowBuffer:
- delete [] *prgByteVals;
- *prgByteVals = NULL;
- delete [] *prgLengths;
- *prgLengths = NULL;
- break;
- default:
- AfxRFXBulkDefault(pFX, szName, *prgByteVals, *prgLengths,
- SQL_C_BINARY, nMaxLength);
- break;
- }
- }
- void AFXAPI AfxRFXBulkDefault(CFieldExchange* pFX, LPCTSTR szName,
- void* pv, long* rgLengths, int nCType, UINT cbValue)
- {
- RETCODE nRetCode;
- switch(pFX->m_nOperation)
- {
- default:
- // Operation not valid for bulk fetch
- ASSERT(FALSE);
- return;
- case CFieldExchange::Name:
- // We require a name
- ASSERT(lstrlen(szName) != 0);
- *pFX->m_pstr += szName;
- *pFX->m_pstr += pFX->m_lpszSeparator;
- break;
- case CFieldExchange::BindFieldToColumn:
- AFX_SQL_SYNC(::SQLBindCol(pFX->m_prs->m_hstmt,
- (UWORD)pFX->m_nFields, (SWORD)nCType, pv, cbValue, rgLengths));
- if (!pFX->m_prs->Check(nRetCode))
- pFX->m_prs->ThrowDBException(nRetCode);
- break;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- // Inline function declarations expanded out-of-line
- #ifndef _AFX_ENABLE_INLINES
- static char _szAfxDbInl[] = "afxdb.inl";
- #undef THIS_FILE
- #define THIS_FILE _szAfxDbInl
- #define _AFXDBRFX_INLINE
- #include "afxdb.inl"
- #endif
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
- /////////////////////////////////////////////////////////////////////////////
|