daocore.cpp 132 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_DB_SEG
  12. #pragma code_seg(AFX_DB_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #pragma comment(lib, "ole32.lib")
  19. #define new DEBUG_NEW
  20. /////////////////////////////////////////////////////////////////////////////
  21. // Maintain DAODBEngine object
  22. _AFX_DAO_STATE::_AFX_DAO_STATE()
  23. {
  24. m_pDAODBEngine = NULL;
  25. m_bOleInitialized = FALSE;
  26. }
  27. _AFX_DAO_STATE::~_AFX_DAO_STATE()
  28. {
  29. // these ASSERTs can trip when:
  30. // ... there any outstanding workspsace objects
  31. ASSERT(m_mapWorkspaces.IsEmpty());
  32. // ... you've not shut down with a call AfxDaoTerm()
  33. ASSERT(m_pDAODBEngine == NULL);
  34. // ... OLE wasn't correctly shut down
  35. ASSERT(!m_bOleInitialized);
  36. }
  37. //////////////////////////////////////////////////////////////////////////
  38. // Helpers
  39. // Index function return value
  40. #define AFX_DAO_DATA_NOT_FOUND (-1L)
  41. #define AFX_DAO_FETCH_PRIMARY_PROPERTIES \
  42. (AFX_DAO_PRIMARY_INFO | AFX_DAO_SECONDARY_INFO | AFX_DAO_ALL_INFO)
  43. #define AFX_DAO_FETCH_SECONDARY_PROPERTIES \
  44. (AFX_DAO_SECONDARY_INFO | AFX_DAO_ALL_INFO)
  45. #define AFX_DAO_FETCH_ALL_PROPERTIES \
  46. AFX_DAO_ALL_INFO
  47. // Info helpers
  48. void AFX_CDECL AfxGetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo,
  49. DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
  50. void AFX_CDECL AfxSetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo);
  51. void AFX_CDECL AfxGetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo,
  52. DWORD dwInfoOptions = AFX_DAO_PRIMARY_INFO);
  53. void AFX_CDECL AfxSetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo);
  54. void AFX_CDECL AfxGetIndexFields(DAOIndex* pDAOIndex,
  55. DAOIndexFields** ppDAOIndexFields);
  56. void AFX_CDECL AfxGetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo);
  57. void AFX_CDECL AfxSetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo);
  58. void AFX_CDECL AfxGetDefaultValue(DAOField* pDAOField, CString& strDefaultValue);
  59. void AFX_CDECL AfxSetDefaultValue(DAOField* pDAOField, CString& strDefaultValue);
  60. // GetRows helper
  61. void AFX_CDECL ThrowGetRowsDaoException(SCODE scode);
  62. // _AFX_DAO_STATE helper
  63. _AFX_DAO_STATE* AFX_CDECL AfxGetDaoState();
  64. //////////////////////////////////////////////////////////////////////////
  65. // Global data
  66. AFX_STATIC_DATA const TCHAR _afxParameters2[] = _T("PARAMETERS ");
  67. AFX_STATIC_DATA const TCHAR _afxSelect2[] = _T("SELECT ");
  68. AFX_STATIC_DATA const TCHAR _afxFrom2[] = _T(" FROM ");
  69. AFX_STATIC_DATA const TCHAR _afxWhere2[] = _T(" WHERE ");
  70. AFX_STATIC_DATA const TCHAR _afxOrderBy2[] = _T(" ORDER BY ");
  71. AFX_STATIC_DATA const TCHAR _afxTransform2[] = _T("TRANSFORM ");
  72. AFX_STATIC_DATA const TCHAR _afxTable2[] = _T("TABLE ");
  73. // Need a static VARIANT for optional DAO parameters
  74. AFX_STATIC_DATA VARIANT _afxOptionalVariant = { VT_ERROR, 0, 0, 0, DISP_E_PARAMNOTFOUND };
  75. // Need a static VARIANT for NULL DAO parameters
  76. AFX_STATIC_DATA VARIANT _afxNullVariant = { VT_NULL, 0, 0, 0, 0 };
  77. //////////////////////////////////////////////////////////////////////////
  78. // Logging helpers
  79. void AFXAPI AfxDaoCheck(SCODE scode, LPCSTR lpszDaoCall,
  80. LPCSTR lpszFile, int nLine, int nError, BOOL bMemOnly)
  81. {
  82. UNUSED(lpszDaoCall);
  83. UNUSED(lpszFile);
  84. UNUSED(nLine);
  85. if (FAILED(scode))
  86. {
  87. #ifdef _DEBUG
  88. if (afxTraceFlags & traceDatabase)
  89. {
  90. TRACE0("\nDAO Call Failed.");
  91. TRACE1("\n\t%hs", lpszDaoCall);
  92. TRACE2("\n\tIn file %hs on line %d", lpszFile, nLine);
  93. TRACE1("\n\tscode = %X\n", scode);
  94. }
  95. #endif
  96. if (scode == E_OUTOFMEMORY)
  97. AfxThrowMemoryException();
  98. else if (!bMemOnly)
  99. AfxThrowDaoException(nError, scode);
  100. }
  101. }
  102. #ifdef _DEBUG
  103. void AFXAPI AfxDaoTrace(SCODE scode, LPCSTR lpszDaoCall,
  104. LPCSTR lpszFile, int nLine)
  105. {
  106. if (FAILED(scode))
  107. {
  108. if (afxTraceFlags & traceDatabase)
  109. {
  110. TRACE0("\nDAO Call Failed.\n\t");
  111. TRACE1("\n%hs", lpszDaoCall);
  112. TRACE2("\nIn file %hs on line %d\n", lpszFile, nLine);
  113. TRACE1("scode = %X\n", scode);
  114. }
  115. }
  116. }
  117. #endif // _DEBUG
  118. //////////////////////////////////////////////////////////////////////////
  119. // Info structure diagnostics
  120. #ifdef _DEBUG
  121. void CDaoErrorInfo::Dump(CDumpContext& dc) const
  122. {
  123. dc << "a CDaoErrorInfo at " << (void*)this;
  124. dc << "\nm_lErrorCode = " << m_lErrorCode;
  125. dc << "\nm_strSource = " << m_strSource;
  126. dc << "\nm_strDescription = " << m_strDescription;
  127. dc << "\nm_strHelpFile = " << m_strHelpFile;
  128. dc << "\nm_lHelpContext = " << m_lHelpContext;
  129. dc << "\n";
  130. }
  131. #endif // _DEBUG
  132. #ifdef _DEBUG
  133. void CDaoWorkspaceInfo::Dump(CDumpContext& dc) const
  134. {
  135. dc << "a CDaoWorkspaceInfo at " << (void*)this;
  136. dc << "\nm_strName = " << m_strName;
  137. dc << "\nm_strUserName = " << m_strUserName;
  138. dc << "\nb = m_bIsolateODBCTrans" << m_bIsolateODBCTrans;
  139. dc << "\n";
  140. }
  141. #endif // _DEBUG
  142. #ifdef _DEBUG
  143. void CDaoDatabaseInfo::Dump(CDumpContext& dc) const
  144. {
  145. dc << "a CDaoDatabaseInfo at " << (void*)this;
  146. dc << "\nm_strName = " << m_strName;
  147. dc << "\nm_bUpdatable = " << m_bUpdatable;
  148. dc << "\nm_bTransactions = " << m_bTransactions;
  149. dc << "\nm_strVersion = " << m_strVersion;
  150. dc << "\nm_lCollatingOrder = " << m_lCollatingOrder;
  151. dc << "\nm_nQueryTimeout = " << m_nQueryTimeout;
  152. dc << "\nm_strConnect = " << m_strConnect;
  153. dc << "\n";
  154. }
  155. #endif // _DEBUG
  156. #ifdef _DEBUG
  157. void CDaoTableDefInfo::Dump(CDumpContext& dc) const
  158. {
  159. dc << "a CDaoTableDefInfo at " << (void*)this;
  160. dc << "\nm_strName = " << m_strName;
  161. dc << "\nm_bUpdatable = " << m_bUpdatable;
  162. dc << "\nm_lAttributes = " << m_lAttributes;
  163. dc << "\nm_dateDateCreated = " << m_dateCreated;
  164. dc << "\nm_dateLastUpdated = " << m_dateLastUpdated;
  165. dc << "\nm_strSrcTableName = " << m_strSrcTableName;
  166. dc << "\nm_strConnect = " << m_strConnect;
  167. dc << "\nm_strValidationRule = " << m_strValidationRule;
  168. dc << "\nm_strValidationText = " << m_strValidationText;
  169. dc << "\nm_lRecordCount = " << m_lRecordCount;
  170. dc << "\n";
  171. }
  172. #endif // _DEBUG
  173. #ifdef _DEBUG
  174. void CDaoFieldInfo::Dump(CDumpContext& dc) const
  175. {
  176. dc << "a CDaoFieldInfo at " << (void*)this;
  177. dc << "\nm_strName = " << m_strName;
  178. dc << "\nm_nType = " << m_nType;
  179. dc << "\nm_lSize = " << m_lSize;
  180. dc << "\nm_lAttributes = " << m_lAttributes;
  181. dc << "\nm_nOrdinalPosition = " << m_nOrdinalPosition;
  182. dc << "\nm_bRequired = " << m_bRequired;
  183. dc << "\nm_bAllowZeroLength = " << m_bAllowZeroLength;
  184. dc << "\nm_lCollatingOrder = " << m_lCollatingOrder;
  185. dc << "\nm_strForeignName = " << m_strForeignName;
  186. dc << "\nm_strSourceField = " << m_strSourceField;
  187. dc << "\nm_strSourceTable = " << m_strSourceTable;
  188. dc << "\nm_strValidationRule = " << m_strValidationRule;
  189. dc << "\nm_strValidationText = " << m_strValidationText;
  190. dc << "\nm_strDefaultValue = " << m_strDefaultValue;
  191. dc << "\n";
  192. }
  193. #endif // _DEBUG
  194. #ifdef _DEBUG
  195. void CDaoIndexFieldInfo::Dump(CDumpContext& dc) const
  196. {
  197. dc << " a CDaoIndexFieldInfo at " << (void*)this;
  198. dc << "\nm_strName = " << m_strName;
  199. dc << "\nm_bDescending = " << m_bDescending;
  200. }
  201. #endif
  202. CDaoIndexInfo::CDaoIndexInfo()
  203. {
  204. m_pFieldInfos = NULL;
  205. m_nFields = 0;
  206. m_bCleanupFieldInfo = FALSE;
  207. }
  208. CDaoIndexInfo::~CDaoIndexInfo()
  209. {
  210. if (m_bCleanupFieldInfo && m_pFieldInfos != NULL)
  211. {
  212. delete[] m_pFieldInfos;
  213. m_pFieldInfos = NULL;
  214. }
  215. }
  216. #ifdef _DEBUG
  217. void CDaoIndexInfo::Dump(CDumpContext& dc) const
  218. {
  219. dc << "a CDaoIndexInfo at " << (void*)this;
  220. dc << "\nm_strName = " << m_strName;
  221. dc << "\nm_nFields = " << m_nFields;
  222. for (int nIndex = 0; nIndex < m_nFields; nIndex++)
  223. m_pFieldInfos[nIndex].Dump(dc);
  224. dc << "\nm_bPrimary = " << m_bPrimary;
  225. dc << "\nm_bUnique = " << m_bUnique;
  226. dc << "\nm_bClustered = " << m_bClustered;
  227. dc << "\nm_bIgnoreNulls = " << m_bIgnoreNulls;
  228. dc << "\nm_bRequired = " << m_bRequired;
  229. dc << "\nm_bForeign = " << m_bForeign;
  230. dc << "\nm_lDistinctCount = " << m_lDistinctCount;
  231. dc << "\n";
  232. }
  233. #endif // _DEBUG
  234. #ifdef _DEBUG
  235. void CDaoRelationFieldInfo::Dump(CDumpContext& dc) const
  236. {
  237. dc << " a CDaoRelationFieldInfo at " << (void*)this;
  238. dc << "\nm_strName = " << m_strName;
  239. dc << "\nm_strForeignName = " << m_strForeignName;
  240. }
  241. #endif
  242. CDaoRelationInfo::CDaoRelationInfo()
  243. {
  244. m_pFieldInfos = NULL;
  245. m_nFields = 0;
  246. m_bCleanupFieldInfo = FALSE;
  247. }
  248. CDaoRelationInfo::~CDaoRelationInfo()
  249. {
  250. if (m_bCleanupFieldInfo && m_pFieldInfos != NULL)
  251. {
  252. delete[] m_pFieldInfos;
  253. m_pFieldInfos = NULL;
  254. }
  255. }
  256. #ifdef _DEBUG
  257. void CDaoRelationInfo::Dump(CDumpContext& dc) const
  258. {
  259. dc << "a CDaoRelationInfo at " << (void*)this;
  260. dc << "\nm_strName = " << m_strName;
  261. dc << "\nm_strTable = " << m_strTable;
  262. dc << "\nm_strForeignTable = " << m_strForeignTable;
  263. dc << "\nm_lAttributes = " << m_lAttributes;
  264. dc << "\nm_nFields = " << m_nFields;
  265. for (int nIndex = 0; nIndex < m_nFields; nIndex++)
  266. m_pFieldInfos[nIndex].Dump(dc);
  267. dc << "\n";
  268. }
  269. #endif // _DEBUG
  270. #ifdef _DEBUG
  271. void CDaoQueryDefInfo::Dump(CDumpContext& dc) const
  272. {
  273. dc << "a CDaoQueryDefInfo at " << (void*)this;
  274. dc << "\nm_strName = " << m_strName;
  275. dc << "\nm_nType = " << m_nType;
  276. dc << "\nm_dateCreated = " << m_dateCreated;
  277. dc << "\nm_dateLastUpdated = " << m_dateLastUpdated;
  278. dc << "\nm_bUpdatable = " << m_bUpdatable;
  279. dc << "\nm_bReturnsRecords = " << m_bReturnsRecords;
  280. dc << "\nm_strSQL = " << m_strSQL;
  281. dc << "\nm_strConnect = " << m_strConnect;
  282. dc << "\nm_nODBCTimeout = " << m_nODBCTimeout;
  283. dc << "\n";
  284. }
  285. #endif // _DEBUG
  286. #ifdef _DEBUG
  287. void CDaoParameterInfo::Dump(CDumpContext& dc) const
  288. {
  289. dc << "a CDaoParameterInfo at " << (void*)this;
  290. dc << "\nm_strName = " << m_strName;
  291. dc << "\nm_nType = " << m_nType;
  292. dc << "\nm_varValue = " << m_varValue;
  293. dc << "\n";
  294. }
  295. #endif // _DEBUG
  296. //////////////////////////////////////////////////////////////////////////
  297. // CDaoException
  298. IMPLEMENT_DYNAMIC(CDaoException, CException)
  299. CDaoException::CDaoException()
  300. {
  301. m_pDAOError = NULL;
  302. m_pDAOErrors = NULL;
  303. m_pErrorInfo = NULL;
  304. }
  305. CDaoException::~CDaoException()
  306. {
  307. delete m_pErrorInfo;
  308. m_pErrorInfo = NULL;
  309. if (m_pDAOErrors != NULL)
  310. {
  311. m_pDAOErrors->Release();
  312. m_pDAOErrors = NULL;
  313. }
  314. if (m_pDAOError != NULL)
  315. {
  316. m_pDAOError->Release();
  317. m_pDAOError = NULL;
  318. }
  319. }
  320. // Operations
  321. short CDaoException::GetErrorCount()
  322. {
  323. short nErrors = 1;
  324. if (m_pDAOErrors == NULL)
  325. InitErrorsCollection();
  326. if (m_nAfxDaoError != AFX_DAO_ERROR_ENGINE_INITIALIZATION)
  327. DAO_CHECK_MEM(m_pDAOErrors->get_Count(&nErrors));
  328. return nErrors;
  329. }
  330. void CDaoException::GetErrorInfo(int nIndex)
  331. {
  332. ASSERT(m_pDAOError == NULL);
  333. if (m_pDAOErrors == NULL)
  334. InitErrorsCollection();
  335. if (m_nAfxDaoError != AFX_DAO_ERROR_ENGINE_INITIALIZATION)
  336. {
  337. // Get DAOError object and fill in error info struct
  338. DAO_CHECK_MEM(m_pDAOErrors->get_Item(
  339. COleVariant((long)nIndex), &m_pDAOError));
  340. FillErrorInfo();
  341. // Clean up
  342. m_pDAOError->Release();
  343. m_pDAOError = NULL;
  344. }
  345. }
  346. BOOL CDaoException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
  347. PUINT pnHelpContext)
  348. {
  349. ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
  350. BOOL bRetCode = FALSE;
  351. if (m_pErrorInfo != NULL)
  352. {
  353. // DAO help context is not a UINT!
  354. // According to DAO it is positive and should be less 10,000,000
  355. if (pnHelpContext != NULL)
  356. *pnHelpContext = (UINT) m_pErrorInfo->m_lHelpContext;
  357. lstrcpyn(lpszError, m_pErrorInfo->m_strDescription, nMaxError-1);
  358. lpszError[nMaxError-1] = '\0';
  359. bRetCode = TRUE;
  360. }
  361. else
  362. {
  363. // Must be MFC DAO class internal error, get error string
  364. CString strError;
  365. if (strError.LoadString(
  366. AFX_IDP_DAO_FIRST + (m_nAfxDaoError - AFX_DAO_ERROR_MIN)))
  367. {
  368. lstrcpyn(lpszError, strError, nMaxError-1);
  369. bRetCode = TRUE;
  370. }
  371. else
  372. ASSERT(FALSE); // Couldn't get resource.
  373. }
  374. return bRetCode;
  375. }
  376. // Implementation
  377. void CDaoException::InitErrorsCollection()
  378. {
  379. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  380. // Engine not initialized!
  381. if (pDaoState->m_pDAODBEngine == NULL)
  382. m_nAfxDaoError = AFX_DAO_ERROR_ENGINE_INITIALIZATION;
  383. else
  384. DAO_CHECK_MEM(pDaoState->m_pDAODBEngine->get_Errors(
  385. &m_pDAOErrors));
  386. }
  387. void CDaoException::FillErrorInfo()
  388. {
  389. ASSERT(m_pDAOError != NULL);
  390. // Allocate the error info structure if necessary
  391. if (m_pErrorInfo == NULL)
  392. m_pErrorInfo = new CDaoErrorInfo;
  393. COleVariant var;
  394. DAO_CHECK_MEM(m_pDAOError->get_Number(
  395. &m_pErrorInfo->m_lErrorCode));
  396. DAO_CHECK_MEM(m_pDAOError->get_Source(&V_BSTR(&var)));
  397. var.vt = VT_BSTR;
  398. m_pErrorInfo->m_strSource = V_BSTRT(&var);
  399. var.Clear();
  400. DAO_CHECK_MEM(m_pDAOError->get_Description(&V_BSTR(&var)));
  401. var.vt = VT_BSTR;
  402. m_pErrorInfo->m_strDescription = V_BSTRT(&var);
  403. var.Clear();
  404. DAO_CHECK_MEM(m_pDAOError->get_HelpFile(&V_BSTR(&var)));
  405. var.vt = VT_BSTR;
  406. m_pErrorInfo->m_strHelpFile = V_BSTRT(&var);
  407. var.Clear();
  408. DAO_CHECK_MEM(m_pDAOError->get_HelpContext(
  409. &m_pErrorInfo->m_lHelpContext));
  410. }
  411. void AFXAPI AfxThrowDaoException(int nAfxDaoError, SCODE scode)
  412. {
  413. CDaoException* pException;
  414. pException = new CDaoException;
  415. pException->m_scode = scode;
  416. if (nAfxDaoError == NO_AFX_DAO_ERROR)
  417. {
  418. TRY
  419. {
  420. int nErrors = pException->GetErrorCount();
  421. for (int nIndex = 0; nIndex < nErrors; nIndex++)
  422. {
  423. pException->GetErrorInfo(nIndex);
  424. #ifdef _DEBUG
  425. if (afxTraceFlags & traceDatabase)
  426. {
  427. TRACE1("\nError Code = %d\n",
  428. pException->m_pErrorInfo->m_lErrorCode);
  429. TRACE1("Source = %s\n",
  430. (LPCTSTR)pException->m_pErrorInfo->m_strSource);
  431. TRACE1("Description = %s\n",
  432. (LPCTSTR)pException->m_pErrorInfo->m_strDescription);
  433. }
  434. #endif // _DEBUG
  435. }
  436. }
  437. CATCH_ALL(e)
  438. {
  439. // No DAO error info
  440. e->Delete();
  441. }
  442. END_CATCH_ALL
  443. }
  444. else
  445. pException->m_nAfxDaoError = nAfxDaoError;
  446. THROW(pException);
  447. }
  448. //////////////////////////////////////////////////////////////////////////
  449. // CDaoWorkspace
  450. IMPLEMENT_DYNAMIC(CDaoWorkspace, CObject)
  451. CDaoWorkspace::CDaoWorkspace()
  452. {
  453. m_pDAOWorkspaces = NULL;
  454. m_pDAOWorkspace = NULL;
  455. m_pDAODatabases = NULL;
  456. m_bOpen = FALSE;
  457. m_bNew = FALSE;
  458. m_nStatus = 0;
  459. }
  460. CDaoWorkspace::~CDaoWorkspace()
  461. {
  462. if (IsOpen())
  463. {
  464. m_nStatus |= AFX_DAO_IMPLICIT_CLOSE;
  465. Close();
  466. }
  467. else if (m_bNew)
  468. {
  469. // Remove the workspace from the AFX_DAO_STATE's map
  470. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  471. pDaoState->m_mapWorkspaces.RemoveKey(this);
  472. }
  473. }
  474. void CDaoWorkspace::Create(LPCTSTR lpszName, LPCTSTR lpszUserName,
  475. LPCTSTR lpszPassword)
  476. {
  477. ASSERT_VALID(this);
  478. ASSERT(!IsOpen());
  479. ASSERT(lpszUserName != NULL);
  480. ASSERT(lpszPassword != NULL);
  481. // Get the DAODBEngine interface and initialize if necessary
  482. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  483. if (pDaoState->m_pDAODBEngine == NULL)
  484. InitializeEngine();
  485. COleVariant varName(lpszName, VT_BSTRT);
  486. COleVariant varUserName(lpszUserName, VT_BSTRT);
  487. COleVariant varPassword(lpszPassword, VT_BSTRT);
  488. DAO_CHECK(pDaoState->m_pDAODBEngine->_30_CreateWorkspace(
  489. V_BSTR(&varName), V_BSTR(&varUserName),
  490. V_BSTR(&varPassword), &m_pDAOWorkspace));
  491. m_bNew = TRUE;
  492. // Add the workspace to map of Open/New CDaoWorkspaces
  493. pDaoState->m_mapWorkspaces.SetAt(this, this);
  494. }
  495. void CDaoWorkspace::Append()
  496. {
  497. ASSERT_VALID(this);
  498. ASSERT(m_bNew);
  499. ASSERT(m_pDAOWorkspace != NULL);
  500. DAOWorkspaces* pDAOWorkspaces;
  501. // Get the DAODBEngine interface and initialize if necessary
  502. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  503. if (pDaoState->m_pDAODBEngine == NULL)
  504. InitializeEngine();
  505. DAO_CHECK(pDaoState->m_pDAODBEngine->get_Workspaces(&pDAOWorkspaces));
  506. TRY
  507. {
  508. DAO_CHECK(pDAOWorkspaces->Append(m_pDAOWorkspace));
  509. }
  510. CATCH_ALL(e)
  511. {
  512. pDAOWorkspaces->Release();
  513. THROW_LAST();
  514. }
  515. END_CATCH_ALL
  516. pDAOWorkspaces->Release();
  517. m_bNew = FALSE;
  518. m_bOpen = TRUE;
  519. }
  520. void CDaoWorkspace::Open(LPCTSTR lpszWorkspaceName)
  521. {
  522. ASSERT_VALID(this);
  523. ASSERT(m_pDAOWorkspaces == NULL);
  524. ASSERT(m_pDAOWorkspace == NULL);
  525. // Re-Opening is invalid.
  526. if (IsOpen())
  527. {
  528. ASSERT(FALSE);
  529. return;
  530. }
  531. // Set the workspace name (or use 0 if opening default)
  532. COleVariant var(lpszWorkspaceName, VT_BSTRT);
  533. if (lpszWorkspaceName == NULL)
  534. {
  535. var = 0L;
  536. // Set status to prevent DAO Workspace Close call
  537. m_nStatus |= AFX_DAO_DEFAULT_WS;
  538. }
  539. // Get the DAODBEngine interface and initialize if necessary
  540. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  541. if (pDaoState->m_pDAODBEngine == NULL)
  542. InitializeEngine();
  543. // Get the workspace from the workspaces collection
  544. DAO_CHECK(pDaoState->m_pDAODBEngine->get_Workspaces(
  545. &m_pDAOWorkspaces));
  546. DAO_CHECK(m_pDAOWorkspaces->get_Item(var, &m_pDAOWorkspace));
  547. m_bOpen = TRUE;
  548. m_pDAOWorkspaces->Release();
  549. m_pDAOWorkspaces = NULL;
  550. // Add the workspace to map of Open/New CDaoWorkspaces
  551. pDaoState->m_mapWorkspaces.SetAt(this, this);
  552. }
  553. void CDaoWorkspace::Close()
  554. {
  555. ASSERT_VALID(this);
  556. if (m_pDAODatabases != NULL)
  557. {
  558. m_pDAODatabases->Release();
  559. m_pDAODatabases = NULL;
  560. }
  561. // Close any Open CDaoDatabases
  562. void* pvKey;
  563. void* pvObject;
  564. POSITION pos = m_mapDatabases.GetStartPosition();
  565. while (pos != NULL)
  566. {
  567. m_mapDatabases.GetNextAssoc(pos, pvKey, pvObject);
  568. ((CDaoDatabase*)pvObject)->Close();
  569. }
  570. m_mapDatabases.RemoveAll();
  571. if (m_pDAOWorkspace != NULL)
  572. {
  573. // If implicit workspace or close, don't call DAO close.
  574. // It will be automatically closed when ref count 0.
  575. if (!(m_nStatus & (AFX_DAO_IMPLICIT_WS | AFX_DAO_IMPLICIT_CLOSE |
  576. AFX_DAO_DEFAULT_WS)))
  577. {
  578. DAO_TRACE(m_pDAOWorkspace->Close());
  579. }
  580. m_pDAOWorkspace->Release();
  581. m_pDAOWorkspace = NULL;
  582. }
  583. if (m_pDAOWorkspaces != NULL)
  584. {
  585. m_pDAOWorkspaces->Release();
  586. m_pDAOWorkspaces = NULL;
  587. }
  588. m_bOpen = FALSE;
  589. m_bNew = FALSE;
  590. m_nStatus &= ~AFX_DAO_DEFAULT_WS;
  591. // Remove the workspace from the AFX_DAO_STATE's map
  592. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  593. pDaoState->m_mapWorkspaces.RemoveKey(this);
  594. }
  595. CString PASCAL CDaoWorkspace::GetVersion()
  596. {
  597. COleVariant var;
  598. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  599. if (pDaoState->m_pDAODBEngine == NULL)
  600. InitializeEngine();
  601. DAO_CHECK(pDaoState->m_pDAODBEngine->get_Version(&V_BSTR(&var)));
  602. var.vt = VT_BSTR;
  603. return V_BSTRT(&var);
  604. }
  605. CString PASCAL CDaoWorkspace::GetIniPath()
  606. {
  607. COleVariant var;
  608. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  609. if (pDaoState->m_pDAODBEngine == NULL)
  610. InitializeEngine();
  611. DAO_CHECK(pDaoState->m_pDAODBEngine->get_IniPath(&V_BSTR(&var)));
  612. var.vt = VT_BSTR;
  613. return V_BSTRT(&var);
  614. }
  615. void PASCAL CDaoWorkspace::SetIniPath(LPCTSTR lpszRegistrySubKey)
  616. {
  617. COleVariant var(lpszRegistrySubKey, VT_BSTRT);
  618. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  619. if (pDaoState->m_pDAODBEngine == NULL)
  620. InitializeEngine();
  621. DAO_CHECK(pDaoState->m_pDAODBEngine->put_IniPath(V_BSTR(&var)));
  622. }
  623. void PASCAL CDaoWorkspace::SetDefaultUser(LPCTSTR lpszDefaultUser)
  624. {
  625. COleVariant var(lpszDefaultUser, VT_BSTRT);
  626. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  627. if (pDaoState->m_pDAODBEngine == NULL)
  628. InitializeEngine();
  629. DAO_CHECK(pDaoState->m_pDAODBEngine->put_DefaultUser(V_BSTR(&var)));
  630. }
  631. void PASCAL CDaoWorkspace::SetDefaultPassword(LPCTSTR lpszPassword)
  632. {
  633. COleVariant var(lpszPassword, VT_BSTRT);
  634. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  635. if (pDaoState->m_pDAODBEngine == NULL)
  636. InitializeEngine();
  637. DAO_CHECK(pDaoState->m_pDAODBEngine->put_DefaultPassword(
  638. V_BSTR(&var)));
  639. }
  640. short PASCAL CDaoWorkspace::GetLoginTimeout()
  641. {
  642. short nSeconds;
  643. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  644. if (pDaoState->m_pDAODBEngine == NULL)
  645. InitializeEngine();
  646. DAO_CHECK(pDaoState->m_pDAODBEngine->get_LoginTimeout(&nSeconds));
  647. return nSeconds;
  648. }
  649. void PASCAL CDaoWorkspace::SetLoginTimeout(short nSeconds)
  650. {
  651. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  652. if (pDaoState->m_pDAODBEngine == NULL)
  653. InitializeEngine();
  654. DAO_CHECK(pDaoState->m_pDAODBEngine->put_LoginTimeout(nSeconds));
  655. }
  656. CString CDaoWorkspace::GetName()
  657. {
  658. ASSERT_VALID(this);
  659. ASSERT(m_pDAOWorkspace != NULL);
  660. COleVariant var;
  661. DAO_CHECK(m_pDAOWorkspace->get_Name(&V_BSTR(&var)));
  662. var.vt = VT_BSTR;
  663. return V_BSTRT(&var);
  664. }
  665. CString CDaoWorkspace::GetUserName()
  666. {
  667. ASSERT_VALID(this);
  668. ASSERT(m_pDAOWorkspace != NULL);
  669. COleVariant var;
  670. DAO_CHECK(m_pDAOWorkspace->get_UserName(&V_BSTR(&var)));
  671. var.vt = VT_BSTR;
  672. return V_BSTRT(&var);
  673. }
  674. void CDaoWorkspace::SetIsolateODBCTrans(BOOL bIsolateODBCTrans)
  675. {
  676. ASSERT_VALID(this);
  677. ASSERT(m_pDAOWorkspace != NULL);
  678. DAO_CHECK(m_pDAOWorkspace->put_IsolateODBCTrans(
  679. (short)(bIsolateODBCTrans ? AFX_DAO_TRUE : AFX_DAO_FALSE)));
  680. }
  681. BOOL CDaoWorkspace::GetIsolateODBCTrans()
  682. {
  683. ASSERT_VALID(this);
  684. ASSERT(m_pDAOWorkspace != NULL);
  685. short nIsolateODBCTrans;
  686. DAO_CHECK(m_pDAOWorkspace->get_IsolateODBCTrans(&nIsolateODBCTrans));
  687. return nIsolateODBCTrans == AFX_DAO_TRUE;
  688. }
  689. void PASCAL CDaoWorkspace::CompactDatabase(LPCTSTR lpszSrcName,
  690. LPCTSTR lpszDestName, LPCTSTR lpszLocale, int nOptions,
  691. LPCTSTR lpszPassword)
  692. {
  693. COleVariant varSrcName(lpszSrcName, VT_BSTRT);
  694. COleVariant varDestName(lpszDestName, VT_BSTRT);
  695. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  696. if (pDaoState->m_pDAODBEngine == NULL)
  697. InitializeEngine();
  698. DAO_CHECK(pDaoState->m_pDAODBEngine->CompactDatabase(
  699. V_BSTR(&varSrcName), V_BSTR(&varDestName),
  700. COleVariant(lpszLocale, VT_BSTRT), COleVariant((long)nOptions),
  701. lpszPassword != NULL ? (VARIANT)COleVariant(lpszPassword, VT_BSTRT) :
  702. _afxOptionalVariant));
  703. }
  704. void PASCAL CDaoWorkspace::CompactDatabase(LPCTSTR lpszSrcName,
  705. LPCTSTR lpszDestName, LPCTSTR lpszLocale, int nOptions)
  706. {
  707. CompactDatabase(lpszSrcName, lpszDestName, lpszLocale, nOptions, NULL);
  708. }
  709. void PASCAL CDaoWorkspace::RepairDatabase(LPCTSTR lpszName)
  710. {
  711. COleVariant varName(lpszName, VT_BSTRT);
  712. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  713. if (pDaoState->m_pDAODBEngine == NULL)
  714. InitializeEngine();
  715. DAO_CHECK(pDaoState->m_pDAODBEngine->RepairDatabase(
  716. V_BSTR(&varName)));
  717. }
  718. void PASCAL CDaoWorkspace::Idle(int nAction)
  719. {
  720. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  721. if (pDaoState->m_pDAODBEngine == NULL)
  722. InitializeEngine();
  723. DAO_CHECK(pDaoState->m_pDAODBEngine->Idle(
  724. COleVariant((long)nAction)));
  725. }
  726. short CDaoWorkspace::GetWorkspaceCount()
  727. {
  728. ASSERT_VALID(this);
  729. short nFields;
  730. if (m_pDAOWorkspaces == NULL)
  731. InitWorkspacesCollection();
  732. DAO_CHECK(m_pDAOWorkspaces->get_Count(&nFields));
  733. return nFields;
  734. }
  735. void CDaoWorkspace::GetWorkspaceInfo(int nIndex,
  736. CDaoWorkspaceInfo& wsinfo, DWORD dwInfoOptions)
  737. {
  738. ASSERT_VALID(this);
  739. if (m_pDAOWorkspaces == NULL)
  740. InitWorkspacesCollection();
  741. // Get DAOWorkspace object and fill in workspace info struct
  742. DAOWorkspace* pDAOWorkspace;
  743. DAO_CHECK(m_pDAOWorkspaces->get_Item(
  744. COleVariant((long)nIndex), &pDAOWorkspace));
  745. FillWorkspaceInfo(pDAOWorkspace, wsinfo, dwInfoOptions);
  746. // Clean up
  747. pDAOWorkspace->Release();
  748. }
  749. void CDaoWorkspace::GetWorkspaceInfo(
  750. LPCTSTR lpszName, CDaoWorkspaceInfo& wsinfo,
  751. DWORD dwInfoOptions)
  752. {
  753. ASSERT_VALID(this);
  754. if (m_pDAOWorkspaces == NULL)
  755. InitWorkspacesCollection();
  756. // Get DAOWorkspace object and fill in workspace info struct
  757. DAOWorkspace* pDAOWorkspace;
  758. DAO_CHECK(m_pDAOWorkspaces->get_Item(
  759. COleVariant(lpszName, VT_BSTRT), &pDAOWorkspace));
  760. FillWorkspaceInfo(pDAOWorkspace, wsinfo, dwInfoOptions);
  761. // Clean up
  762. pDAOWorkspace->Release();
  763. }
  764. short CDaoWorkspace::GetDatabaseCount()
  765. {
  766. ASSERT_VALID(this);
  767. if (m_pDAODatabases == NULL)
  768. InitDatabasesCollection();
  769. short nFields;
  770. DAO_CHECK(m_pDAODatabases->get_Count(&nFields));
  771. return nFields;
  772. }
  773. void CDaoWorkspace::GetDatabaseInfo(int nIndex, CDaoDatabaseInfo& dbinfo,
  774. DWORD dwInfoOptions)
  775. {
  776. ASSERT_VALID(this);
  777. if (m_pDAODatabases == NULL)
  778. InitDatabasesCollection();
  779. // Get DAODatabase object and fill in database info struct
  780. DAODatabase* pDAODatabase;
  781. DAO_CHECK(m_pDAODatabases->get_Item(
  782. COleVariant((long)nIndex), &pDAODatabase));
  783. FillDatabaseInfo(pDAODatabase, dbinfo, dwInfoOptions);
  784. // Clean up
  785. pDAODatabase->Release();
  786. }
  787. void CDaoWorkspace::GetDatabaseInfo(LPCTSTR lpszName,
  788. CDaoDatabaseInfo& dbinfo, DWORD dwInfoOptions)
  789. {
  790. ASSERT_VALID(this);
  791. if (m_pDAODatabases == NULL)
  792. InitDatabasesCollection();
  793. // Get DAODatabase object and fill in database info struct
  794. DAODatabase* pDAODatabase;
  795. DAO_CHECK(m_pDAODatabases->get_Item(
  796. COleVariant(lpszName, VT_BSTRT), &pDAODatabase));
  797. FillDatabaseInfo(pDAODatabase, dbinfo, dwInfoOptions);
  798. // Clean up
  799. pDAODatabase->Release();
  800. }
  801. void CDaoWorkspace::BeginTrans()
  802. {
  803. ASSERT_VALID(this);
  804. ASSERT(IsOpen());
  805. ASSERT(m_pDAOWorkspace != NULL);
  806. DAO_CHECK(m_pDAOWorkspace->BeginTrans());
  807. }
  808. // Determine whether to use DAO 3.6, 3.5, or 3.0
  809. // Use DAO 3.0 if DLL build and not built with MFC 4.21 or later
  810. // Use DAO 3.6 if MFC 6.01 or later
  811. // otherwise, DAO 3.5
  812. #ifndef _AFXDLL
  813. #if _MFC_VER >= 0x0601
  814. #define _AfxDetermineDaoVersion() (36)
  815. #else
  816. #define _AfxDetermineDaoVersion() (35)
  817. #endif
  818. #else // dynamically because of DLL
  819. static inline BYTE _AfxDetermineDaoVersion()
  820. {
  821. BYTE bReturn = 35;
  822. #ifdef _AFXDLL
  823. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  824. if (pModuleState->m_dwVersion < 0x421)
  825. bReturn = 30;
  826. else if (pModuleState->m_dwVersion >= 0x0601)
  827. bReturn = 36;
  828. #endif // _AFXDLL
  829. return bReturn;
  830. }
  831. #endif
  832. void CDaoWorkspace::CommitTrans()
  833. {
  834. ASSERT_VALID(this);
  835. ASSERT(IsOpen());
  836. ASSERT(m_pDAOWorkspace != NULL);
  837. BYTE bUseDao = _AfxDetermineDaoVersion();
  838. if (bUseDao == 35 || bUseDao == 36)
  839. {
  840. // Call DAO 3.5 or 3.6 method with no option set.
  841. // CommitTrans option parameter not yet supported.
  842. DAO_CHECK(m_pDAOWorkspace->CommitTrans(0));
  843. }
  844. else
  845. {
  846. // Call DAO 3.0 method
  847. // The DAO 3.0 version of CommitTrans takes no params
  848. // so cast CommitTrans to method that takes no params.
  849. HRESULT (STDMETHODCALLTYPE DAOWorkspace::*pMethod)() = (HRESULT (STDMETHODCALLTYPE DAOWorkspace::*)())m_pDAOWorkspace->CommitTrans;
  850. DAO_CHECK((m_pDAOWorkspace->*pMethod)());
  851. }
  852. }
  853. void CDaoWorkspace::Rollback()
  854. {
  855. ASSERT_VALID(this);
  856. ASSERT(IsOpen());
  857. ASSERT(m_pDAOWorkspace != NULL);
  858. DAO_CHECK(m_pDAOWorkspace->Rollback());
  859. }
  860. //Implementation
  861. void AFX_CDECL CDaoWorkspace::InitializeEngine()
  862. {
  863. AfxDaoInit();
  864. }
  865. void CDaoWorkspace::InitWorkspacesCollection()
  866. {
  867. ASSERT_VALID(this);
  868. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  869. if (pDaoState->m_pDAODBEngine == NULL)
  870. InitializeEngine();
  871. DAO_CHECK(pDaoState->m_pDAODBEngine->get_Workspaces(
  872. &m_pDAOWorkspaces));
  873. }
  874. void CDaoWorkspace::FillWorkspaceInfo(DAOWorkspace* pDAOWorkspace,
  875. CDaoWorkspaceInfo& wsinfo, DWORD dwOptions)
  876. {
  877. ASSERT_VALID(this);
  878. ASSERT(pDAOWorkspace != NULL);
  879. ASSERT(dwOptions != 0);
  880. COleVariant var;
  881. short nBool;
  882. if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  883. {
  884. DAO_CHECK(pDAOWorkspace->get_Name(&V_BSTR(&var)));
  885. var.vt = VT_BSTR;
  886. wsinfo.m_strName = V_BSTRT(&var);
  887. var.Clear();
  888. }
  889. if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  890. {
  891. DAO_CHECK(pDAOWorkspace->get_UserName(&V_BSTR(&var)));
  892. var.vt = VT_BSTR;
  893. wsinfo.m_strUserName = V_BSTRT(&var);
  894. var.Clear();
  895. }
  896. if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
  897. {
  898. DAO_CHECK(pDAOWorkspace->get_IsolateODBCTrans(&nBool));
  899. wsinfo.m_bIsolateODBCTrans = nBool == AFX_DAO_TRUE;
  900. }
  901. }
  902. void CDaoWorkspace::InitDatabasesCollection()
  903. {
  904. ASSERT_VALID(this);
  905. DAO_CHECK(m_pDAOWorkspace->get_Databases(&m_pDAODatabases));
  906. }
  907. void CDaoWorkspace::FillDatabaseInfo(DAODatabase* pDAODatabase,
  908. CDaoDatabaseInfo& dbinfo, DWORD dwOptions)
  909. {
  910. ASSERT_VALID(this);
  911. ASSERT(pDAODatabase != NULL);
  912. ASSERT(dwOptions != 0);
  913. COleVariant var;
  914. short nBool;
  915. if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  916. {
  917. DAO_CHECK(pDAODatabase->get_Name(&V_BSTR(&var)));
  918. var.vt = VT_BSTR;
  919. dbinfo.m_strName = V_BSTRT(&var);
  920. var.Clear();
  921. DAO_CHECK(pDAODatabase->get_Updatable(&nBool));
  922. dbinfo.m_bUpdatable = nBool == AFX_DAO_TRUE;
  923. DAO_CHECK(pDAODatabase->get_Transactions(&nBool));
  924. dbinfo.m_bTransactions = nBool == AFX_DAO_TRUE;
  925. }
  926. if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  927. {
  928. DAO_CHECK(pDAODatabase->get_Version(
  929. &V_BSTR(&var)));
  930. var.vt = VT_BSTR;
  931. dbinfo.m_strVersion = V_BSTRT(&var);
  932. var.Clear();
  933. DAO_CHECK(pDAODatabase->get_CollatingOrder(
  934. &dbinfo.m_lCollatingOrder));
  935. DAO_CHECK(pDAODatabase->get_QueryTimeout(
  936. &dbinfo.m_nQueryTimeout));
  937. }
  938. if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
  939. {
  940. DAO_CHECK(pDAODatabase->get_Connect(
  941. &V_BSTR(&var)));
  942. var.vt = VT_BSTR;
  943. dbinfo.m_strConnect = V_BSTRT(&var);
  944. var.Clear();
  945. }
  946. }
  947. void CDaoWorkspace::ThrowDaoException(int nAfxDaoError)
  948. {
  949. ASSERT_VALID(this);
  950. AfxThrowDaoException(nAfxDaoError);
  951. }
  952. #ifdef _DEBUG
  953. void CDaoWorkspace::AssertValid() const
  954. {
  955. CObject::AssertValid();
  956. }
  957. void CDaoWorkspace::Dump(CDumpContext& dc) const
  958. {
  959. ASSERT_VALID(this);
  960. CObject::Dump(dc);
  961. dc << "m_bOpen = " << m_bOpen;
  962. dc << "\nm_bNew = " << m_bNew;
  963. dc << "\nm_nStatus = " << m_nStatus;
  964. dc << "\n";
  965. }
  966. #endif //_DEBUG
  967. //////////////////////////////////////////////////////////////////////////
  968. // CDaoDatabase
  969. IMPLEMENT_DYNAMIC(CDaoDatabase, CObject)
  970. CDaoDatabase::CDaoDatabase(CDaoWorkspace* pWorkspace)
  971. {
  972. m_bOpen = FALSE;
  973. m_pDAODatabase = NULL;
  974. m_pDAOTableDefs = NULL;
  975. m_pDAORelations = NULL;
  976. m_pDAOQueryDefs = NULL;
  977. m_pDAORecordsets = NULL;
  978. m_pWorkspace = pWorkspace;
  979. m_nStatus = 0;
  980. }
  981. CDaoDatabase::~CDaoDatabase()
  982. {
  983. if (IsOpen())
  984. Close();
  985. // Clean up workspace if necessary
  986. if (m_pWorkspace != NULL && (m_nStatus & AFX_DAO_IMPLICIT_WS))
  987. {
  988. m_pWorkspace->Close();
  989. delete m_pWorkspace;
  990. m_pWorkspace = NULL;
  991. }
  992. }
  993. void CDaoDatabase::Create(LPCTSTR lpszName, LPCTSTR lpszLocale,
  994. int nOptions)
  995. {
  996. ASSERT_VALID(this);
  997. ASSERT(!IsOpen());
  998. // Allocate and maintain workspace if necessary
  999. InitWorkspace();
  1000. COleVariant varName(lpszName, VT_BSTRT);
  1001. COleVariant varLocale(lpszLocale, VT_BSTRT);
  1002. DAO_CHECK(m_pWorkspace->m_pDAOWorkspace->CreateDatabase(V_BSTR(&varName),
  1003. V_BSTR(&varLocale), COleVariant((long)nOptions),
  1004. &m_pDAODatabase));
  1005. m_bOpen = TRUE;
  1006. // Add the database to map of Open CDaoDatabases
  1007. m_pWorkspace->m_mapDatabases.SetAt(this, this);
  1008. }
  1009. void CDaoDatabase::Open(LPCTSTR lpszName, BOOL bExclusive,
  1010. BOOL bReadOnly, LPCTSTR lpszConnect)
  1011. {
  1012. ASSERT_VALID(this);
  1013. // Re-Opening is invalid.
  1014. if (IsOpen())
  1015. {
  1016. ASSERT(FALSE);
  1017. return;
  1018. }
  1019. // Allocate, maintain and/or open workspace if necessary
  1020. InitWorkspace();
  1021. COleVariant var(lpszName, VT_BSTRT);
  1022. DAO_CHECK(m_pWorkspace->m_pDAOWorkspace->OpenDatabase(
  1023. V_BSTR(&var),
  1024. COleVariant((long)bExclusive, VT_BOOL),
  1025. COleVariant((long)bReadOnly, VT_BOOL),
  1026. COleVariant(lpszConnect, VT_BSTRT),
  1027. &m_pDAODatabase));
  1028. m_bOpen = TRUE;
  1029. // Add the database to map of Open CDaoDatabases
  1030. m_pWorkspace->m_mapDatabases.SetAt(this, this);
  1031. }
  1032. // Disconnect connection
  1033. void CDaoDatabase::Close()
  1034. {
  1035. ASSERT_VALID(this);
  1036. if (m_pDAORecordsets != NULL)
  1037. {
  1038. m_pDAORecordsets->Release();
  1039. m_pDAORecordsets = NULL;
  1040. }
  1041. if (m_pDAOQueryDefs != NULL)
  1042. {
  1043. m_pDAOQueryDefs->Release();
  1044. m_pDAOQueryDefs = NULL;
  1045. }
  1046. if (m_pDAORelations != NULL)
  1047. {
  1048. m_pDAORelations->Release();
  1049. m_pDAORelations = NULL;
  1050. }
  1051. if (m_pDAOTableDefs != NULL)
  1052. {
  1053. m_pDAOTableDefs->Release();
  1054. m_pDAOTableDefs = NULL;
  1055. }
  1056. // Close any Open CDaoRecordsets
  1057. void* pvKey;
  1058. void* pvObject;
  1059. POSITION pos = m_mapRecordsets.GetStartPosition();
  1060. while (pos != NULL)
  1061. {
  1062. m_mapRecordsets.GetNextAssoc(pos, pvKey, pvObject);
  1063. ((CDaoRecordset*)pvObject)->Close();
  1064. }
  1065. m_mapRecordsets.RemoveAll();
  1066. // Close any Open CDaoQueryDefs
  1067. pos = m_mapQueryDefs.GetStartPosition();
  1068. while (pos != NULL)
  1069. {
  1070. m_mapQueryDefs.GetNextAssoc(pos, pvKey, pvObject);
  1071. ((CDaoQueryDef*)pvObject)->Close();
  1072. }
  1073. m_mapQueryDefs.RemoveAll();
  1074. // Close any Open CDaoTableDefs
  1075. pos = m_mapTableDefs.GetStartPosition();
  1076. while (pos != NULL)
  1077. {
  1078. m_mapTableDefs.GetNextAssoc(pos, pvKey, pvObject);
  1079. ((CDaoTableDef*)pvObject)->Close();
  1080. }
  1081. m_mapTableDefs.RemoveAll();
  1082. if (m_pDAODatabase != NULL)
  1083. {
  1084. // If implicit database, don't close.
  1085. // It will be automatically closed when ref count 0.
  1086. if (!(m_nStatus & AFX_DAO_IMPLICIT_DB))
  1087. DAO_TRACE(m_pDAODatabase->Close());
  1088. m_pDAODatabase->Release();
  1089. m_pDAODatabase = NULL;
  1090. }
  1091. m_bOpen = FALSE;
  1092. // Remove the CDaoDatabase from the CDaoWorkspace's map
  1093. m_pWorkspace->m_mapDatabases.RemoveKey(this);
  1094. }
  1095. BOOL CDaoDatabase::CanUpdate()
  1096. {
  1097. ASSERT_VALID(this);
  1098. ASSERT(IsOpen());
  1099. ASSERT(m_pDAODatabase != NULL);
  1100. short nUpdatable;
  1101. DAO_CHECK(m_pDAODatabase->get_Updatable(&nUpdatable));
  1102. return nUpdatable == AFX_DAO_TRUE;
  1103. }
  1104. BOOL CDaoDatabase::CanTransact()
  1105. {
  1106. ASSERT_VALID(this);
  1107. ASSERT(IsOpen());
  1108. ASSERT(m_pDAODatabase != NULL);
  1109. short nTransactable;
  1110. DAO_CHECK(m_pDAODatabase->get_Transactions(&nTransactable));
  1111. return nTransactable == AFX_DAO_TRUE;
  1112. }
  1113. CString CDaoDatabase::GetName()
  1114. {
  1115. ASSERT_VALID(this);
  1116. ASSERT(IsOpen());
  1117. ASSERT(m_pDAODatabase != NULL);
  1118. COleVariant var;
  1119. DAO_CHECK(m_pDAODatabase->get_Name(&V_BSTR(&var)));
  1120. var.vt = VT_BSTR;
  1121. return V_BSTRT(&var);
  1122. }
  1123. CString CDaoDatabase::GetConnect()
  1124. {
  1125. ASSERT_VALID(this);
  1126. ASSERT(IsOpen());
  1127. ASSERT(m_pDAODatabase != NULL);
  1128. COleVariant var;
  1129. DAO_CHECK(m_pDAODatabase->get_Connect(&V_BSTR(&var)));
  1130. var.vt = VT_BSTR;
  1131. return V_BSTRT(&var);
  1132. }
  1133. CString CDaoDatabase::GetVersion()
  1134. {
  1135. ASSERT_VALID(this);
  1136. ASSERT(IsOpen());
  1137. ASSERT(m_pDAODatabase != NULL);
  1138. COleVariant var;
  1139. DAO_CHECK(m_pDAODatabase->get_Version(&V_BSTR(&var)));
  1140. var.vt = VT_BSTR;
  1141. return V_BSTRT(&var);
  1142. }
  1143. short CDaoDatabase::GetQueryTimeout()
  1144. {
  1145. ASSERT_VALID(this);
  1146. ASSERT(IsOpen());
  1147. ASSERT(m_pDAODatabase != NULL);
  1148. short nQueryTimeout;
  1149. DAO_CHECK(m_pDAODatabase->get_QueryTimeout(&nQueryTimeout));
  1150. return nQueryTimeout;
  1151. }
  1152. void CDaoDatabase::SetQueryTimeout(short nSeconds)
  1153. {
  1154. ASSERT_VALID(this);
  1155. ASSERT(IsOpen());
  1156. ASSERT(m_pDAODatabase != NULL);
  1157. DAO_CHECK(m_pDAODatabase->put_QueryTimeout(nSeconds));
  1158. }
  1159. long CDaoDatabase::GetRecordsAffected()
  1160. {
  1161. ASSERT_VALID(this);
  1162. ASSERT(IsOpen());
  1163. ASSERT(m_pDAODatabase != NULL);
  1164. long lRecordsAffected;
  1165. DAO_CHECK(m_pDAODatabase->get_RecordsAffected(&lRecordsAffected));
  1166. return lRecordsAffected;
  1167. }
  1168. void CDaoDatabase::DeleteTableDef(LPCTSTR lpszName)
  1169. {
  1170. ASSERT_VALID(this);
  1171. ASSERT(IsOpen());
  1172. if (m_pDAOTableDefs == NULL)
  1173. InitTableDefsCollection();
  1174. COleVariant var(lpszName, VT_BSTRT);
  1175. DAO_CHECK(m_pDAOTableDefs->Delete(V_BSTR(&var)));
  1176. }
  1177. void CDaoDatabase::DeleteQueryDef(LPCTSTR lpszName)
  1178. {
  1179. ASSERT_VALID(this);
  1180. ASSERT(IsOpen());
  1181. if (m_pDAOQueryDefs == NULL)
  1182. InitQueryDefsCollection();
  1183. COleVariant var(lpszName, VT_BSTRT);
  1184. DAO_CHECK(m_pDAOQueryDefs->Delete(V_BSTR(&var)));
  1185. }
  1186. void CDaoDatabase::CreateRelation(LPCTSTR lpszName, LPCTSTR lpszTable,
  1187. LPCTSTR lpszForeignTable, long lAttributes, LPCTSTR lpszField,
  1188. LPCTSTR lpszForeignField)
  1189. {
  1190. ASSERT_VALID(this);
  1191. CDaoRelationInfo relinfo;
  1192. CDaoRelationFieldInfo fieldinfo;
  1193. relinfo.m_strName = lpszName;
  1194. relinfo.m_strTable = lpszTable;
  1195. relinfo.m_strForeignTable = lpszForeignTable;
  1196. relinfo.m_lAttributes = lAttributes;
  1197. relinfo.m_nFields = 1;
  1198. relinfo.m_pFieldInfos = &fieldinfo;
  1199. relinfo.m_pFieldInfos->m_strName = lpszField;
  1200. relinfo.m_pFieldInfos->m_strForeignName = lpszForeignField;
  1201. CreateRelation(relinfo);
  1202. }
  1203. void CDaoDatabase::CreateRelation(CDaoRelationInfo& relinfo)
  1204. {
  1205. ASSERT_VALID(this);
  1206. ASSERT(IsOpen());
  1207. ASSERT(relinfo.m_nFields > 0);
  1208. // Initialize relations collection so that relation can be appended later
  1209. if (m_pDAORelations == NULL)
  1210. InitRelationsCollection();
  1211. DAORelation* pDAORelation = NULL;
  1212. DAOFields* pDAOFields = NULL;
  1213. DAOField* pDAOField = NULL;
  1214. // Create the relation
  1215. DAO_CHECK(m_pDAODatabase->CreateRelation(
  1216. COleVariant(relinfo.m_strName, VT_BSTRT),
  1217. COleVariant(relinfo.m_strTable, VT_BSTRT),
  1218. COleVariant(relinfo.m_strForeignTable, VT_BSTRT),
  1219. COleVariant(relinfo.m_lAttributes), &pDAORelation));
  1220. TRY
  1221. {
  1222. // Get the fields collection for later append of created field
  1223. DAO_CHECK(pDAORelation->get_Fields(&pDAOFields));
  1224. // Create field(s) and set the name and foreign name
  1225. for (int nIndex = 0; nIndex < relinfo.m_nFields; nIndex++)
  1226. {
  1227. DAO_CHECK(pDAORelation->CreateField(
  1228. COleVariant(relinfo.m_pFieldInfos[nIndex].m_strName, VT_BSTRT),
  1229. _afxOptionalVariant, _afxOptionalVariant, &pDAOField));
  1230. COleVariant var(relinfo.m_pFieldInfos[nIndex].m_strForeignName, VT_BSTRT);
  1231. DAO_CHECK(pDAOField->put_ForeignName(V_BSTR(&var)));
  1232. // Append the field to relation fields collection and release
  1233. DAO_CHECK(pDAOFields->Append(pDAOField));
  1234. pDAOField->Release();
  1235. }
  1236. DAO_CHECK(m_pDAORelations->Append(pDAORelation));
  1237. }
  1238. CATCH_ALL(e)
  1239. {
  1240. // Clean up before throw
  1241. if (pDAOField != NULL)
  1242. pDAOField->Release();
  1243. if (pDAOFields != NULL)
  1244. pDAOFields->Release();
  1245. pDAORelation->Release();
  1246. THROW_LAST();
  1247. }
  1248. END_CATCH_ALL
  1249. // Clean up
  1250. if (pDAOField != NULL)
  1251. pDAOField->Release();
  1252. pDAOFields->Release();
  1253. pDAORelation->Release();
  1254. }
  1255. void CDaoDatabase::DeleteRelation(LPCTSTR lpszName)
  1256. {
  1257. ASSERT_VALID(this);
  1258. ASSERT(IsOpen());
  1259. if (m_pDAORelations == NULL)
  1260. InitRelationsCollection();
  1261. COleVariant var(lpszName, VT_BSTRT);
  1262. DAO_CHECK(m_pDAORelations->Delete(V_BSTR(&var)));
  1263. }
  1264. void CDaoDatabase::Execute(LPCTSTR lpszSQL, int nOptions)
  1265. {
  1266. ASSERT_VALID(this);
  1267. ASSERT(m_pDAODatabase != NULL);
  1268. COleVariant var(lpszSQL, VT_BSTRT);
  1269. DAO_CHECK(m_pDAODatabase->Execute(
  1270. V_BSTR(&var), COleVariant((long)nOptions)));
  1271. }
  1272. short CDaoDatabase::GetTableDefCount()
  1273. {
  1274. ASSERT_VALID(this);
  1275. short nTables;
  1276. if (m_pDAOTableDefs == NULL)
  1277. InitTableDefsCollection();
  1278. DAO_CHECK(m_pDAOTableDefs->get_Count(&nTables));
  1279. return nTables;
  1280. }
  1281. void CDaoDatabase::GetTableDefInfo(int nIndex, CDaoTableDefInfo& tabledefinfo,
  1282. DWORD dwInfoOptions)
  1283. {
  1284. ASSERT_VALID(this);
  1285. if (m_pDAOTableDefs == NULL)
  1286. InitTableDefsCollection();
  1287. // Get DAOTableDef object and fill in table info struct
  1288. DAOTableDef* pDAOTableDef;
  1289. DAO_CHECK(m_pDAOTableDefs->get_Item(
  1290. COleVariant((long)nIndex), &pDAOTableDef));
  1291. FillTableDefInfo(pDAOTableDef, tabledefinfo, dwInfoOptions);
  1292. // Clean up
  1293. pDAOTableDef->Release();
  1294. }
  1295. void CDaoDatabase::GetTableDefInfo(LPCTSTR lpszName,
  1296. CDaoTableDefInfo& tabledefinfo, DWORD dwInfoOptions)
  1297. {
  1298. ASSERT_VALID(this);
  1299. if (m_pDAOTableDefs == NULL)
  1300. InitTableDefsCollection();
  1301. // Get DAOTableDef object and fill in table info struct
  1302. DAOTableDef* pDAOTableDef;
  1303. DAO_CHECK(m_pDAOTableDefs->get_Item(
  1304. COleVariant(lpszName, VT_BSTRT), &pDAOTableDef));
  1305. FillTableDefInfo(pDAOTableDef, tabledefinfo, dwInfoOptions);
  1306. // Clean up
  1307. pDAOTableDef->Release();
  1308. }
  1309. short CDaoDatabase::GetRelationCount()
  1310. {
  1311. ASSERT_VALID(this);
  1312. short nRelations;
  1313. if (m_pDAORelations == NULL)
  1314. InitRelationsCollection();
  1315. DAO_CHECK(m_pDAORelations->get_Count(&nRelations));
  1316. return nRelations;
  1317. }
  1318. void CDaoDatabase::GetRelationInfo(int nIndex, CDaoRelationInfo& relinfo,
  1319. DWORD dwInfoOptions)
  1320. {
  1321. ASSERT_VALID(this);
  1322. if (m_pDAORelations == NULL)
  1323. InitRelationsCollection();
  1324. // Get DAORelation object and fill in relation info struct
  1325. DAORelation* pDAORelation;
  1326. DAO_CHECK(m_pDAORelations->get_Item(
  1327. COleVariant((long)nIndex), &pDAORelation));
  1328. FillRelationInfo(pDAORelation, relinfo, dwInfoOptions);
  1329. // Clean up
  1330. pDAORelation->Release();
  1331. }
  1332. void CDaoDatabase::GetRelationInfo(LPCTSTR lpszName,
  1333. CDaoRelationInfo& relinfo, DWORD dwInfoOptions)
  1334. {
  1335. ASSERT_VALID(this);
  1336. if (m_pDAORelations == NULL)
  1337. InitRelationsCollection();
  1338. // Get DAORelation object and fill in relation info struct
  1339. DAORelation* pDAORelation;
  1340. DAO_CHECK(m_pDAORelations->get_Item(
  1341. COleVariant(lpszName, VT_BSTRT), &pDAORelation));
  1342. FillRelationInfo(pDAORelation, relinfo, dwInfoOptions);
  1343. // Clean up
  1344. pDAORelation->Release();
  1345. }
  1346. short CDaoDatabase::GetQueryDefCount()
  1347. {
  1348. ASSERT_VALID(this);
  1349. short nQueryDefs;
  1350. if (m_pDAOQueryDefs == NULL)
  1351. InitQueryDefsCollection();
  1352. DAO_CHECK(m_pDAOQueryDefs->get_Count(&nQueryDefs));
  1353. return nQueryDefs;
  1354. }
  1355. void CDaoDatabase::GetQueryDefInfo(int nIndex, CDaoQueryDefInfo& querydefinfo,
  1356. DWORD dwInfoOptions)
  1357. {
  1358. ASSERT_VALID(this);
  1359. if (m_pDAOQueryDefs == NULL)
  1360. InitQueryDefsCollection();
  1361. // Get DAOQueryDef object and fill in query info struct
  1362. DAOQueryDef* pDAOQueryDef;
  1363. DAO_CHECK(m_pDAOQueryDefs->get_Item(
  1364. COleVariant((long)nIndex), &pDAOQueryDef));
  1365. FillQueryDefInfo(pDAOQueryDef, querydefinfo, dwInfoOptions);
  1366. // Clean up
  1367. pDAOQueryDef->Release();
  1368. }
  1369. void CDaoDatabase::GetQueryDefInfo(LPCTSTR lpszName,
  1370. CDaoQueryDefInfo& querydefinfo, DWORD dwInfoOptions)
  1371. {
  1372. ASSERT_VALID(this);
  1373. if (m_pDAOQueryDefs == NULL)
  1374. InitQueryDefsCollection();
  1375. // Get DAOQueryDef object and fill in query info struct
  1376. DAOQueryDef* pDAOQueryDef;
  1377. DAO_CHECK(m_pDAOQueryDefs->get_Item(
  1378. COleVariant(lpszName, VT_BSTRT), &pDAOQueryDef));
  1379. FillQueryDefInfo(pDAOQueryDef, querydefinfo, dwInfoOptions);
  1380. // Clean up
  1381. pDAOQueryDef->Release();
  1382. }
  1383. // Implementation
  1384. void CDaoDatabase::InitWorkspace()
  1385. {
  1386. ASSERT_VALID(this);
  1387. if (m_pWorkspace == NULL)
  1388. {
  1389. // Allocate workspace and mark as implicit
  1390. m_pWorkspace = new CDaoWorkspace;
  1391. m_pWorkspace->m_nStatus |= AFX_DAO_IMPLICIT_WS;
  1392. m_nStatus |= AFX_DAO_IMPLICIT_WS;
  1393. }
  1394. // Open workspace if not open and not new (unappended)
  1395. if (!m_pWorkspace->IsOpen() && !m_pWorkspace->IsNew())
  1396. {
  1397. // Open the default workspace
  1398. m_pWorkspace->Open();
  1399. }
  1400. }
  1401. void CDaoDatabase::InitTableDefsCollection()
  1402. {
  1403. ASSERT_VALID(this);
  1404. DAO_CHECK(m_pDAODatabase->get_TableDefs(&m_pDAOTableDefs));
  1405. }
  1406. void CDaoDatabase::FillTableDefInfo(DAOTableDef* pDAOTableDef,
  1407. CDaoTableDefInfo& tabledefinfo, DWORD dwOptions)
  1408. {
  1409. ASSERT_VALID(this);
  1410. ASSERT(pDAOTableDef != NULL);
  1411. ASSERT(dwOptions != 0);
  1412. COleVariant var;
  1413. short nBool;
  1414. if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  1415. {
  1416. DAO_CHECK(pDAOTableDef->get_Name(&V_BSTR(&var)));
  1417. var.vt = VT_BSTR;
  1418. tabledefinfo.m_strName = V_BSTRT(&var);
  1419. var.Clear();
  1420. DAO_CHECK(pDAOTableDef->get_Updatable(&nBool));
  1421. tabledefinfo.m_bUpdatable = nBool == AFX_DAO_TRUE;
  1422. DAO_CHECK(pDAOTableDef->get_Attributes(
  1423. &tabledefinfo.m_lAttributes));
  1424. }
  1425. if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  1426. {
  1427. DAO_CHECK(pDAOTableDef->get_DateCreated(&var));
  1428. tabledefinfo.m_dateCreated = var;
  1429. DAO_CHECK(pDAOTableDef->get_LastUpdated(&var));
  1430. tabledefinfo.m_dateLastUpdated = var;
  1431. DAO_CHECK(pDAOTableDef->get_SourceTableName(
  1432. &V_BSTR(&var)));
  1433. var.vt = VT_BSTR;
  1434. tabledefinfo.m_strSrcTableName = V_BSTRT(&var);
  1435. var.Clear();
  1436. DAO_CHECK(pDAOTableDef->get_Connect(
  1437. &V_BSTR(&var)));
  1438. var.vt = VT_BSTR;
  1439. tabledefinfo.m_strConnect = V_BSTRT(&var);
  1440. var.Clear();
  1441. DAO_CHECK(pDAOTableDef->get_ValidationRule(
  1442. &V_BSTR(&var)));
  1443. var.vt = VT_BSTR;
  1444. tabledefinfo.m_strValidationRule = V_BSTRT(&var);
  1445. var.Clear();
  1446. DAO_CHECK(pDAOTableDef->get_ValidationText(
  1447. &V_BSTR(&var)));
  1448. var.vt = VT_BSTR;
  1449. tabledefinfo.m_strValidationText = V_BSTRT(&var);
  1450. var.Clear();
  1451. }
  1452. // This may be expensive, so only get it if absolutely necessary
  1453. if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
  1454. {
  1455. DAO_CHECK(pDAOTableDef->get_RecordCount(
  1456. &tabledefinfo.m_lRecordCount));
  1457. }
  1458. }
  1459. void CDaoDatabase::InitRelationsCollection()
  1460. {
  1461. ASSERT_VALID(this);
  1462. DAO_CHECK(m_pDAODatabase->get_Relations(&m_pDAORelations));
  1463. }
  1464. void CDaoDatabase::FillRelationInfo(DAORelation* pDAORelation,
  1465. CDaoRelationInfo& relinfo, DWORD dwOptions)
  1466. {
  1467. ASSERT_VALID(this);
  1468. ASSERT(pDAORelation != NULL);
  1469. ASSERT(dwOptions != 0);
  1470. COleVariant var;
  1471. if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  1472. {
  1473. // All the relation info is primary
  1474. DAO_CHECK(pDAORelation->get_Name(&V_BSTR(&var)));
  1475. var.vt = VT_BSTR;
  1476. relinfo.m_strName = V_BSTRT(&var);
  1477. var.Clear();
  1478. DAO_CHECK(pDAORelation->get_Table(&V_BSTR(&var)));
  1479. var.vt = VT_BSTR;
  1480. relinfo.m_strTable = V_BSTRT(&var);
  1481. var.Clear();
  1482. DAO_CHECK(pDAORelation->get_ForeignTable(
  1483. &V_BSTR(&var)));
  1484. var.vt = VT_BSTR;
  1485. relinfo.m_strForeignTable = V_BSTRT(&var);
  1486. var.Clear();
  1487. }
  1488. if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  1489. {
  1490. DAOFields* pDAOFields = NULL;
  1491. DAOField* pDAOField = NULL;
  1492. DAO_CHECK(pDAORelation->get_Attributes(
  1493. &relinfo.m_lAttributes));
  1494. // Get the fields collection
  1495. DAO_CHECK(pDAORelation->get_Fields(&pDAOFields));
  1496. TRY
  1497. {
  1498. // Get the number of fields in the relation
  1499. short nCount;
  1500. DAO_CHECK(pDAOFields->get_Count(&nCount));
  1501. // Allocate or reallocate memory for array if necessary
  1502. if (nCount != relinfo.m_nFields)
  1503. {
  1504. if (relinfo.m_nFields != 0)
  1505. {
  1506. // Check that allocation is correct.
  1507. ASSERT(relinfo.m_nFields == 0 ||
  1508. relinfo.m_bCleanupFieldInfo);
  1509. delete[] relinfo.m_pFieldInfos;
  1510. relinfo.m_pFieldInfos = NULL;
  1511. }
  1512. // Now allocate required memory
  1513. relinfo.m_pFieldInfos = new CDaoRelationFieldInfo[nCount];
  1514. relinfo.m_bCleanupFieldInfo = TRUE;
  1515. relinfo.m_nFields = nCount;
  1516. }
  1517. // Now get field info for each field
  1518. for (int nIndex = 0; nIndex < relinfo.m_nFields; nIndex++)
  1519. {
  1520. // Get the field item
  1521. DAO_CHECK(pDAOFields->get_Item(
  1522. COleVariant((long)nIndex), &pDAOField));
  1523. // Get the field name
  1524. DAO_CHECK(pDAOField->get_Name(&V_BSTR(&var)));
  1525. var.vt = VT_BSTR;
  1526. relinfo.m_pFieldInfos[nIndex].m_strName =
  1527. V_BSTRT(&var);
  1528. var.Clear();
  1529. // Get the foreign field name
  1530. DAO_CHECK(pDAOField->get_ForeignName(&V_BSTR(&var)));
  1531. var.vt = VT_BSTR;
  1532. relinfo.m_pFieldInfos[nIndex].m_strForeignName =
  1533. V_BSTRT(&var);
  1534. var.Clear();
  1535. // Release and reset the field object
  1536. pDAOField->Release();
  1537. pDAOField = NULL;
  1538. }
  1539. }
  1540. CATCH_ALL(e)
  1541. {
  1542. if (pDAOField != NULL)
  1543. pDAOField->Release();
  1544. pDAOFields->Release();
  1545. THROW_LAST();
  1546. }
  1547. END_CATCH_ALL
  1548. // Release the objects
  1549. pDAOFields->Release();
  1550. }
  1551. }
  1552. void CDaoDatabase::InitQueryDefsCollection()
  1553. {
  1554. ASSERT_VALID(this);
  1555. DAO_CHECK(m_pDAODatabase->get_QueryDefs(&m_pDAOQueryDefs));
  1556. }
  1557. void CDaoDatabase::FillQueryDefInfo(DAOQueryDef* pDAOQueryDef,
  1558. CDaoQueryDefInfo& querydefinfo, DWORD dwOptions)
  1559. {
  1560. ASSERT_VALID(this);
  1561. ASSERT(pDAOQueryDef != NULL);
  1562. ASSERT(dwOptions != 0);
  1563. COleVariant var;
  1564. short nBool;
  1565. if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  1566. {
  1567. DAO_CHECK(pDAOQueryDef->get_Name(&V_BSTR(&var)));
  1568. var.vt = VT_BSTR;
  1569. querydefinfo.m_strName = V_BSTRT(&var);
  1570. var.Clear();
  1571. DAO_CHECK(pDAOQueryDef->get_Type(&querydefinfo.m_nType));
  1572. }
  1573. if (dwOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  1574. {
  1575. DAO_CHECK(pDAOQueryDef->get_Updatable(&nBool));
  1576. querydefinfo.m_bUpdatable = nBool == AFX_DAO_TRUE;
  1577. DAO_CHECK(pDAOQueryDef->get_DateCreated(&var));
  1578. querydefinfo.m_dateCreated = var;
  1579. DAO_CHECK(pDAOQueryDef->get_LastUpdated(&var));
  1580. querydefinfo.m_dateLastUpdated = var;
  1581. DAO_CHECK(pDAOQueryDef->get_ReturnsRecords(&nBool));
  1582. querydefinfo.m_bReturnsRecords = nBool == AFX_DAO_TRUE;
  1583. }
  1584. if (dwOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
  1585. {
  1586. DAO_CHECK(pDAOQueryDef->get_SQL(&V_BSTR(&var)));
  1587. var.vt = VT_BSTR;
  1588. querydefinfo.m_strSQL = V_BSTRT(&var);
  1589. var.Clear();
  1590. DAO_CHECK(pDAOQueryDef->get_Connect(&V_BSTR(
  1591. (LPVARIANT)var)));
  1592. var.vt = VT_BSTR;
  1593. querydefinfo.m_strConnect = V_BSTRT(&var);
  1594. var.Clear();
  1595. // DAO will display ODBC connect dialog
  1596. // if data source no longer exists. This must
  1597. // be avoided during bulk info retrieval.
  1598. // Call CDaoQueryDef::GetODBCTimeout directly.
  1599. // DAO_CHECK(pDAOQueryDef->get_ODBCTimeout(
  1600. // &querydefinfo.m_nODBCTimeout));
  1601. // Set the m_nODBCTimeout variable to invalid value.
  1602. querydefinfo.m_nODBCTimeout = -1;
  1603. }
  1604. }
  1605. void CDaoDatabase::ThrowDaoException(int nAfxDaoError)
  1606. {
  1607. ASSERT_VALID(this);
  1608. AfxThrowDaoException(nAfxDaoError);
  1609. }
  1610. #ifdef _DEBUG
  1611. void CDaoDatabase::AssertValid() const
  1612. {
  1613. CObject::AssertValid();
  1614. }
  1615. void CDaoDatabase::Dump(CDumpContext& dc) const
  1616. {
  1617. ASSERT_VALID(this);
  1618. CObject::Dump(dc);
  1619. dc << "m_bOpen = " << m_bOpen;
  1620. dc << "\nm_nStatus = " << m_nStatus;
  1621. dc << "\n";
  1622. }
  1623. #endif //_DEBUG
  1624. //////////////////////////////////////////////////////////////////////////
  1625. // CDaoTableDef
  1626. IMPLEMENT_DYNAMIC(CDaoTableDef, CObject)
  1627. CDaoTableDef::CDaoTableDef(CDaoDatabase* pDatabase)
  1628. {
  1629. m_bOpen = FALSE;
  1630. m_bNew = FALSE;
  1631. m_pDatabase = pDatabase;
  1632. m_pDAOTableDef = NULL;
  1633. m_pDAOFields = NULL;
  1634. m_pDAOIndexes = NULL;
  1635. }
  1636. CDaoTableDef::~CDaoTableDef()
  1637. {
  1638. if (IsOpen())
  1639. Close();
  1640. else if (m_bNew)
  1641. {
  1642. // Remove the tabledef from the CDaoDatabase's map
  1643. m_pDatabase->m_mapTableDefs.RemoveKey(this);
  1644. }
  1645. }
  1646. void CDaoTableDef::Create(LPCTSTR lpszName, long lAttributes,
  1647. LPCTSTR lpszSrcTable, LPCTSTR lpszConnect)
  1648. {
  1649. ASSERT_VALID(this);
  1650. ASSERT(!IsOpen());
  1651. DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateTableDef(
  1652. COleVariant(lpszName, VT_BSTRT), COleVariant(lAttributes),
  1653. COleVariant(lpszSrcTable, VT_BSTRT),
  1654. COleVariant(lpszConnect, VT_BSTRT), &m_pDAOTableDef));
  1655. m_bNew = TRUE;
  1656. // Add the tabledef to map of Open/New CDaoTableDefs
  1657. m_pDatabase->m_mapTableDefs.SetAt(this, this);
  1658. }
  1659. void CDaoTableDef::Append()
  1660. {
  1661. ASSERT_VALID(this);
  1662. ASSERT(m_bNew);
  1663. ASSERT(m_pDAOTableDef != NULL);
  1664. DAOTableDefs* pDAOTableDefs;
  1665. DAO_CHECK(m_pDatabase->m_pDAODatabase->get_TableDefs(
  1666. &pDAOTableDefs));
  1667. TRY
  1668. {
  1669. DAO_CHECK(pDAOTableDefs->Append(m_pDAOTableDef));
  1670. }
  1671. CATCH_ALL(e)
  1672. {
  1673. pDAOTableDefs->Release();
  1674. THROW_LAST();
  1675. }
  1676. END_CATCH_ALL
  1677. pDAOTableDefs->Release();
  1678. m_bNew = FALSE;
  1679. m_bOpen = TRUE;
  1680. }
  1681. void CDaoTableDef::Open(LPCTSTR lpszName)
  1682. {
  1683. ASSERT_VALID(this);
  1684. ASSERT(lpszName != NULL);
  1685. // Re-open is invalid
  1686. if (IsOpen())
  1687. {
  1688. ASSERT(FALSE);
  1689. return;
  1690. }
  1691. DAOTableDefs* pDAOTableDefs = NULL;
  1692. TRY
  1693. {
  1694. DAO_CHECK(m_pDatabase->m_pDAODatabase->get_TableDefs(
  1695. &pDAOTableDefs));
  1696. DAO_CHECK(pDAOTableDefs->get_Item(
  1697. COleVariant(lpszName, VT_BSTRT),&m_pDAOTableDef));
  1698. }
  1699. CATCH_ALL(e)
  1700. {
  1701. if (pDAOTableDefs != NULL)
  1702. pDAOTableDefs->Release();
  1703. THROW_LAST();
  1704. }
  1705. END_CATCH_ALL
  1706. pDAOTableDefs->Release();
  1707. m_bOpen = TRUE;
  1708. // Add the tabledef to map of Open/New CDaoTableDefs
  1709. m_pDatabase->m_mapTableDefs.SetAt(this, this);
  1710. }
  1711. void CDaoTableDef::Close()
  1712. {
  1713. ASSERT_VALID(this);
  1714. if (m_pDAOIndexes != NULL)
  1715. {
  1716. m_pDAOIndexes->Release();
  1717. m_pDAOIndexes = NULL;
  1718. }
  1719. if (m_pDAOFields != NULL)
  1720. {
  1721. m_pDAOFields->Release();
  1722. m_pDAOFields = NULL;
  1723. }
  1724. if (m_pDAOTableDef != NULL)
  1725. {
  1726. m_pDAOTableDef->Release();
  1727. m_pDAOTableDef = NULL;
  1728. }
  1729. m_bOpen = FALSE;
  1730. m_bNew = FALSE;
  1731. // Remove the tabledef from the CDaoDatabase's map
  1732. m_pDatabase->m_mapTableDefs.RemoveKey(this);
  1733. }
  1734. BOOL CDaoTableDef::CanUpdate()
  1735. {
  1736. ASSERT_VALID(this);
  1737. ASSERT(IsOpen());
  1738. ASSERT(m_pDAOTableDef != NULL);
  1739. short nUpdatable;
  1740. DAO_CHECK(m_pDAOTableDef->get_Updatable(&nUpdatable));
  1741. return nUpdatable == AFX_DAO_TRUE;
  1742. }
  1743. void CDaoTableDef::SetName(LPCTSTR lpszName)
  1744. {
  1745. ASSERT_VALID(this);
  1746. ASSERT(IsOpen() || m_bNew);
  1747. ASSERT(m_pDAOTableDef != NULL);
  1748. COleVariant var(lpszName, VT_BSTRT);
  1749. DAO_CHECK(m_pDAOTableDef->put_Name(V_BSTR(&var)));
  1750. }
  1751. CString CDaoTableDef::GetName()
  1752. {
  1753. ASSERT_VALID(this);
  1754. ASSERT(IsOpen());
  1755. ASSERT(m_pDAOTableDef != NULL);
  1756. COleVariant var;
  1757. DAO_CHECK(m_pDAOTableDef->get_Name(&V_BSTR(&var)));
  1758. var.vt = VT_BSTR;
  1759. return V_BSTRT(&var);
  1760. }
  1761. void CDaoTableDef::SetSourceTableName(LPCTSTR lpszSrcTableName)
  1762. {
  1763. ASSERT_VALID(this);
  1764. ASSERT(IsOpen() || m_bNew);
  1765. ASSERT(m_pDAOTableDef != NULL);
  1766. COleVariant var(lpszSrcTableName, VT_BSTRT);
  1767. DAO_CHECK(m_pDAOTableDef->put_SourceTableName(
  1768. V_BSTR(&var)));
  1769. }
  1770. CString CDaoTableDef::GetSourceTableName()
  1771. {
  1772. ASSERT_VALID(this);
  1773. ASSERT(IsOpen());
  1774. ASSERT(m_pDAOTableDef != NULL);
  1775. COleVariant var;
  1776. DAO_CHECK(m_pDAOTableDef->get_SourceTableName(
  1777. &V_BSTR(&var)));
  1778. var.vt = VT_BSTR;
  1779. return V_BSTRT(&var);
  1780. }
  1781. void CDaoTableDef::SetConnect(LPCTSTR lpszConnect)
  1782. {
  1783. ASSERT_VALID(this);
  1784. ASSERT(IsOpen() || m_bNew);
  1785. ASSERT(m_pDAOTableDef != NULL);
  1786. COleVariant var(lpszConnect, VT_BSTRT);
  1787. DAO_CHECK(m_pDAOTableDef->put_Connect(V_BSTR(&var)));
  1788. }
  1789. CString CDaoTableDef::GetConnect()
  1790. {
  1791. ASSERT_VALID(this);
  1792. ASSERT(IsOpen());
  1793. ASSERT(m_pDAOTableDef != NULL);
  1794. COleVariant var;
  1795. DAO_CHECK(m_pDAOTableDef->get_Connect(&V_BSTR(&var)));
  1796. var.vt = VT_BSTR;
  1797. return V_BSTRT(&var);
  1798. }
  1799. void CDaoTableDef::SetAttributes(long lAttributes)
  1800. {
  1801. ASSERT_VALID(this);
  1802. ASSERT(IsOpen() || m_bNew);
  1803. ASSERT(m_pDAOTableDef != NULL);
  1804. DAO_CHECK(m_pDAOTableDef->put_Attributes(lAttributes));
  1805. }
  1806. long CDaoTableDef::GetAttributes()
  1807. {
  1808. ASSERT_VALID(this);
  1809. ASSERT(IsOpen());
  1810. ASSERT(m_pDAOTableDef != NULL);
  1811. long lAttributes;
  1812. DAO_CHECK(m_pDAOTableDef->get_Attributes(&lAttributes));
  1813. return lAttributes;
  1814. }
  1815. COleDateTime CDaoTableDef::GetDateCreated()
  1816. {
  1817. ASSERT_VALID(this);
  1818. ASSERT(IsOpen());
  1819. ASSERT(m_pDAOTableDef != NULL);
  1820. COleVariant varDate;
  1821. DAO_CHECK(m_pDAOTableDef->get_DateCreated(&varDate));
  1822. return varDate.date;
  1823. }
  1824. COleDateTime CDaoTableDef::GetDateLastUpdated()
  1825. {
  1826. ASSERT_VALID(this);
  1827. ASSERT(IsOpen());
  1828. ASSERT(m_pDAOTableDef != NULL);
  1829. COleVariant varDate;
  1830. DAO_CHECK(m_pDAOTableDef->get_LastUpdated(&varDate));
  1831. return varDate.date;
  1832. }
  1833. void CDaoTableDef::SetValidationRule(
  1834. LPCTSTR lpszValidationRule)
  1835. {
  1836. ASSERT_VALID(this);
  1837. ASSERT(IsOpen() || m_bNew);
  1838. ASSERT(m_pDAOTableDef != NULL);
  1839. COleVariant var(lpszValidationRule, VT_BSTRT);
  1840. DAO_CHECK(m_pDAOTableDef->put_ValidationRule(
  1841. V_BSTR(&var)));
  1842. }
  1843. CString CDaoTableDef::GetValidationRule()
  1844. {
  1845. ASSERT_VALID(this);
  1846. ASSERT(IsOpen());
  1847. ASSERT(m_pDAOTableDef != NULL);
  1848. COleVariant var;
  1849. DAO_CHECK(m_pDAOTableDef->get_ValidationRule(
  1850. &V_BSTR(&var)));
  1851. var.vt = VT_BSTR;
  1852. return V_BSTRT(&var);
  1853. }
  1854. void CDaoTableDef::SetValidationText(
  1855. LPCTSTR lpszValidationText)
  1856. {
  1857. ASSERT_VALID(this);
  1858. ASSERT(IsOpen() || m_bNew);
  1859. ASSERT(m_pDAOTableDef != NULL);
  1860. COleVariant var(lpszValidationText, VT_BSTRT);
  1861. DAO_CHECK(m_pDAOTableDef->put_ValidationText(
  1862. V_BSTR(&var)));
  1863. }
  1864. CString CDaoTableDef::GetValidationText()
  1865. {
  1866. ASSERT_VALID(this);
  1867. ASSERT(IsOpen());
  1868. ASSERT(m_pDAOTableDef != NULL);
  1869. COleVariant var;
  1870. DAO_CHECK(m_pDAOTableDef->get_ValidationText(
  1871. &V_BSTR(&var)));
  1872. var.vt = VT_BSTR;
  1873. return V_BSTRT(&var);
  1874. }
  1875. long CDaoTableDef::GetRecordCount()
  1876. {
  1877. ASSERT_VALID(this);
  1878. ASSERT(IsOpen());
  1879. ASSERT(m_pDAOTableDef != NULL);
  1880. long lRecordCount;
  1881. DAO_CHECK(m_pDAOTableDef->get_RecordCount(&lRecordCount));
  1882. return lRecordCount;
  1883. }
  1884. void CDaoTableDef::CreateField(LPCTSTR lpszName, short nType, long lSize,
  1885. long lAttributes)
  1886. {
  1887. ASSERT_VALID(this);
  1888. CDaoFieldInfo fieldinfo;
  1889. // Initialize everything so only correct properties will be set
  1890. fieldinfo.m_strName = lpszName;
  1891. fieldinfo.m_nType = nType;
  1892. fieldinfo.m_lSize = lSize;
  1893. fieldinfo.m_lAttributes = lAttributes;
  1894. fieldinfo.m_nOrdinalPosition = 0;
  1895. fieldinfo.m_bRequired = FALSE;
  1896. fieldinfo.m_bAllowZeroLength = FALSE;
  1897. fieldinfo.m_lCollatingOrder = 0;
  1898. CreateField(fieldinfo);
  1899. }
  1900. void CDaoTableDef::CreateField(CDaoFieldInfo& fieldinfo)
  1901. {
  1902. ASSERT_VALID(this);
  1903. DAOField* pDAOField;
  1904. // Create the DAO field object (setting basic properties)
  1905. DAO_CHECK(m_pDAOTableDef->CreateField(
  1906. COleVariant(fieldinfo.m_strName, VT_BSTRT),
  1907. COleVariant(fieldinfo.m_nType),
  1908. COleVariant(fieldinfo.m_lSize), &pDAOField));
  1909. TRY
  1910. {
  1911. // Basic properties already set, so set the rest
  1912. AfxSetFieldInfo(pDAOField, fieldinfo);
  1913. // Append the field object to the fields collection
  1914. if (m_pDAOFields == NULL)
  1915. InitFieldsCollection();
  1916. DAO_CHECK(m_pDAOFields->Append(pDAOField));
  1917. }
  1918. CATCH_ALL(e)
  1919. {
  1920. pDAOField->Release();
  1921. THROW_LAST();
  1922. }
  1923. END_CATCH_ALL
  1924. pDAOField->Release();
  1925. }
  1926. void CDaoTableDef::DeleteField(LPCTSTR lpszName)
  1927. {
  1928. ASSERT_VALID(this);
  1929. ASSERT(lpszName != NULL);
  1930. if (m_pDAOFields == NULL)
  1931. InitFieldsCollection();
  1932. COleVariant var(lpszName, VT_BSTRT);
  1933. DAO_CHECK(m_pDAOFields->Delete(V_BSTR(&var)));
  1934. }
  1935. void CDaoTableDef::DeleteField(int nIndex)
  1936. {
  1937. ASSERT_VALID(this);
  1938. CDaoFieldInfo fieldinfo;
  1939. GetFieldInfo(nIndex, fieldinfo, AFX_DAO_PRIMARY_INFO);
  1940. DeleteField((LPCTSTR)fieldinfo.m_strName);
  1941. }
  1942. void CDaoTableDef::CreateIndex(CDaoIndexInfo& indexinfo)
  1943. {
  1944. ASSERT_VALID(this);
  1945. DAOIndex* pDAOIndex;
  1946. DAO_CHECK(m_pDAOTableDef->CreateIndex(
  1947. COleVariant(indexinfo.m_strName, VT_BSTRT), &pDAOIndex));
  1948. TRY
  1949. {
  1950. // Set the index info
  1951. AfxSetIndexInfo(pDAOIndex, indexinfo);
  1952. // Append the field object to the fields collection
  1953. if (m_pDAOIndexes == NULL)
  1954. InitIndexesCollection();
  1955. DAO_CHECK(m_pDAOIndexes->Append(pDAOIndex));
  1956. }
  1957. CATCH_ALL(e)
  1958. {
  1959. pDAOIndex->Release();
  1960. THROW_LAST();
  1961. }
  1962. END_CATCH_ALL
  1963. pDAOIndex->Release();
  1964. }
  1965. void CDaoTableDef::DeleteIndex(LPCTSTR lpszName)
  1966. {
  1967. ASSERT_VALID(this);
  1968. ASSERT(lpszName != NULL);
  1969. if (m_pDAOIndexes == NULL)
  1970. InitIndexesCollection();
  1971. COleVariant var(lpszName, VT_BSTRT);
  1972. DAO_CHECK(m_pDAOIndexes->Delete(V_BSTR(&var)));
  1973. }
  1974. void CDaoTableDef::DeleteIndex(int nIndex)
  1975. {
  1976. ASSERT_VALID(this);
  1977. CDaoIndexInfo indexinfo;
  1978. GetIndexInfo(nIndex, indexinfo, AFX_DAO_PRIMARY_INFO);
  1979. DeleteIndex((LPCTSTR)indexinfo.m_strName);
  1980. }
  1981. short CDaoTableDef::GetFieldCount()
  1982. {
  1983. ASSERT_VALID(this);
  1984. short nFields;
  1985. if (m_pDAOFields == NULL)
  1986. InitFieldsCollection();
  1987. DAO_CHECK(m_pDAOFields->get_Count(&nFields));
  1988. return nFields;
  1989. }
  1990. void CDaoTableDef::GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
  1991. DWORD dwInfoOptions)
  1992. {
  1993. ASSERT_VALID(this);
  1994. if (m_pDAOFields == NULL)
  1995. InitFieldsCollection();
  1996. // Get DAOField object and fill in field info struct
  1997. DAOField* pDAOField;
  1998. DAO_CHECK(m_pDAOFields->get_Item(
  1999. COleVariant((long)nIndex), &pDAOField));
  2000. AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
  2001. // Clean up
  2002. pDAOField->Release();
  2003. }
  2004. void CDaoTableDef::GetFieldInfo(LPCTSTR lpszName,
  2005. CDaoFieldInfo& fieldinfo, DWORD dwInfoOptions)
  2006. {
  2007. ASSERT_VALID(this);
  2008. if (m_pDAOFields == NULL)
  2009. InitFieldsCollection();
  2010. // Get DAOField object and fill in field info struct
  2011. DAOField* pDAOField;
  2012. DAO_CHECK(m_pDAOFields->get_Item(
  2013. COleVariant(lpszName, VT_BSTRT), &pDAOField));
  2014. AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
  2015. // Clean up
  2016. pDAOField->Release();
  2017. }
  2018. short CDaoTableDef::GetIndexCount()
  2019. {
  2020. ASSERT_VALID(this);
  2021. short nIndexes;
  2022. if (m_pDAOIndexes == NULL)
  2023. InitIndexesCollection();
  2024. DAO_CHECK(m_pDAOIndexes->get_Count(&nIndexes));
  2025. return nIndexes;
  2026. }
  2027. void CDaoTableDef::GetIndexInfo(int nIndex, CDaoIndexInfo& indexinfo,
  2028. DWORD dwInfoOptions)
  2029. {
  2030. ASSERT_VALID(this);
  2031. if (m_pDAOIndexes == NULL)
  2032. InitIndexesCollection();
  2033. // Get DAOField object and fill in field info struct
  2034. DAOIndex* pDAOIndex;
  2035. DAO_CHECK(m_pDAOIndexes->get_Item(
  2036. COleVariant((long)nIndex), &pDAOIndex));
  2037. AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
  2038. // Clean up
  2039. pDAOIndex->Release();
  2040. }
  2041. void CDaoTableDef::GetIndexInfo(LPCTSTR lpszName,
  2042. CDaoIndexInfo& indexinfo, DWORD dwInfoOptions)
  2043. {
  2044. ASSERT_VALID(this);
  2045. if (m_pDAOIndexes == NULL)
  2046. InitIndexesCollection();
  2047. // Get DAOField object and fill in field info struct
  2048. DAOIndex* pDAOIndex;
  2049. DAO_CHECK(m_pDAOIndexes->get_Item(
  2050. COleVariant(lpszName, VT_BSTRT), &pDAOIndex));
  2051. AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
  2052. // Clean up
  2053. pDAOIndex->Release();
  2054. }
  2055. void CDaoTableDef::RefreshLink()
  2056. {
  2057. ASSERT_VALID(this);
  2058. ASSERT(IsOpen());
  2059. ASSERT(m_pDAOTableDef != NULL);
  2060. DAO_CHECK(m_pDAOTableDef->RefreshLink());
  2061. }
  2062. //Implementation functions
  2063. void CDaoTableDef::InitFieldsCollection()
  2064. {
  2065. ASSERT_VALID(this);
  2066. DAO_CHECK(m_pDAOTableDef->get_Fields(&m_pDAOFields));
  2067. }
  2068. void CDaoTableDef::InitIndexesCollection()
  2069. {
  2070. ASSERT_VALID(this);
  2071. DAO_CHECK(m_pDAOTableDef->get_Indexes(&m_pDAOIndexes));
  2072. }
  2073. void CDaoTableDef::ThrowDaoException(int nAfxDaoError)
  2074. {
  2075. ASSERT_VALID(this);
  2076. AfxThrowDaoException(nAfxDaoError);
  2077. }
  2078. #ifdef _DEBUG
  2079. void CDaoTableDef::AssertValid() const
  2080. {
  2081. CObject::AssertValid();
  2082. }
  2083. void CDaoTableDef::Dump(CDumpContext& dc) const
  2084. {
  2085. ASSERT_VALID(this);
  2086. CObject::Dump(dc);
  2087. dc << "m_bOpen = " << m_bOpen;
  2088. dc << "\nm_bNew = " << m_bNew;
  2089. dc << "\n";
  2090. }
  2091. #endif //_DEBUG
  2092. //////////////////////////////////////////////////////////////////////////
  2093. // CDaoQueryDef
  2094. IMPLEMENT_DYNAMIC(CDaoQueryDef, CObject)
  2095. CDaoQueryDef::CDaoQueryDef(CDaoDatabase* pDatabase)
  2096. {
  2097. m_bOpen = FALSE;
  2098. m_bNew = FALSE;
  2099. m_pDatabase = pDatabase;
  2100. m_pDAOQueryDef = NULL;
  2101. m_pDAOParameters = NULL;
  2102. m_pDAOFields = NULL;
  2103. }
  2104. CDaoQueryDef::~CDaoQueryDef()
  2105. {
  2106. if (IsOpen())
  2107. Close();
  2108. else if (m_bNew)
  2109. {
  2110. // Remove the querydef from the CDaoDatabase's map
  2111. m_pDatabase->m_mapQueryDefs.RemoveKey(this);
  2112. }
  2113. }
  2114. void CDaoQueryDef::Create(LPCTSTR lpszName, LPCTSTR lpszSQL)
  2115. {
  2116. ASSERT_VALID(this);
  2117. ASSERT(!IsOpen());
  2118. // Create a temp querydef if lpszName is NULL or empty string
  2119. if (lpszName == NULL || *lpszName == '\0')
  2120. {
  2121. DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateQueryDef(
  2122. COleVariant(_T(""), VT_BSTRT),
  2123. COleVariant(lpszSQL, VT_BSTRT),
  2124. &m_pDAOQueryDef));
  2125. m_bOpen = TRUE;
  2126. }
  2127. else
  2128. {
  2129. // Create a template querydef
  2130. // (preventing automatic append to QueryDefs collection)
  2131. DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateQueryDef(
  2132. _afxOptionalVariant, _afxOptionalVariant, &m_pDAOQueryDef));
  2133. m_bNew = TRUE;
  2134. // Now set the name and SQL if necessary
  2135. SetName(lpszName);
  2136. if (lpszSQL != NULL)
  2137. SetSQL(lpszSQL);
  2138. }
  2139. // Add the querydef to map of Open/New CDaoQueryDefs
  2140. m_pDatabase->m_mapQueryDefs.SetAt(this, this);
  2141. }
  2142. void CDaoQueryDef::Append()
  2143. {
  2144. ASSERT_VALID(this);
  2145. ASSERT(m_bNew);
  2146. ASSERT(m_pDAOQueryDef != NULL);
  2147. DAOQueryDefs* pDAOQueryDefs;
  2148. DAO_CHECK(m_pDatabase->m_pDAODatabase->get_QueryDefs(
  2149. &pDAOQueryDefs));
  2150. TRY
  2151. {
  2152. DAO_CHECK(pDAOQueryDefs->Append(m_pDAOQueryDef));
  2153. }
  2154. CATCH_ALL(e)
  2155. {
  2156. pDAOQueryDefs->Release();
  2157. THROW_LAST();
  2158. }
  2159. END_CATCH_ALL
  2160. pDAOQueryDefs->Release();
  2161. m_bNew = FALSE;
  2162. m_bOpen = TRUE;
  2163. }
  2164. // Open a pre-defined query or create a temp query
  2165. void CDaoQueryDef::Open(LPCTSTR lpszName)
  2166. {
  2167. ASSERT_VALID(this);
  2168. ASSERT(!m_bNew);
  2169. // Re-open is not allowed
  2170. if (IsOpen())
  2171. {
  2172. ASSERT(FALSE);
  2173. return;
  2174. }
  2175. // Null lpszName implies create a temp query
  2176. if (lpszName == NULL)
  2177. {
  2178. DAO_CHECK(m_pDatabase->m_pDAODatabase->CreateQueryDef(
  2179. COleVariant(_T(""), VT_BSTRT), _afxOptionalVariant, &m_pDAOQueryDef));
  2180. }
  2181. else
  2182. {
  2183. COleVariant varName(lpszName, VT_BSTRT);
  2184. DAO_CHECK(m_pDatabase->m_pDAODatabase->OpenQueryDef(
  2185. V_BSTR(&varName), &m_pDAOQueryDef));
  2186. }
  2187. m_bOpen = TRUE;
  2188. // Add the querydef to map of Open/New CDaoQueryDefs
  2189. m_pDatabase->m_mapQueryDefs.SetAt(this, this);
  2190. }
  2191. void CDaoQueryDef::Close()
  2192. {
  2193. ASSERT_VALID(this);
  2194. if (m_pDAOParameters != NULL)
  2195. {
  2196. m_pDAOParameters->Release();
  2197. m_pDAOParameters = NULL;
  2198. }
  2199. if (m_pDAOFields != NULL)
  2200. {
  2201. m_pDAOFields->Release();
  2202. m_pDAOFields = NULL;
  2203. }
  2204. if (m_pDAOQueryDef != NULL)
  2205. {
  2206. // DAO Close is a no op, but call it anyway
  2207. DAO_TRACE(m_pDAOQueryDef->Close());
  2208. m_pDAOQueryDef->Release();
  2209. m_pDAOQueryDef = NULL;
  2210. }
  2211. m_bOpen = FALSE;
  2212. m_bNew = FALSE;
  2213. // Remove the querydef from the CDaoDatabase's map
  2214. m_pDatabase->m_mapQueryDefs.RemoveKey(this);
  2215. }
  2216. BOOL CDaoQueryDef::CanUpdate()
  2217. {
  2218. ASSERT_VALID(this);
  2219. ASSERT(IsOpen());
  2220. short nUpdatable;
  2221. DAO_CHECK(m_pDAOQueryDef->get_Updatable(&nUpdatable));
  2222. return nUpdatable == AFX_DAO_TRUE;
  2223. }
  2224. CString CDaoQueryDef::GetName()
  2225. {
  2226. ASSERT_VALID(this);
  2227. ASSERT(IsOpen());
  2228. COleVariant var;
  2229. DAO_CHECK(m_pDAOQueryDef->get_Name(&V_BSTR(&var)));
  2230. var.vt = VT_BSTR;
  2231. return V_BSTRT(&var);
  2232. }
  2233. void CDaoQueryDef::SetName(LPCTSTR lpszName)
  2234. {
  2235. ASSERT_VALID(this);
  2236. ASSERT(IsOpen() || m_bNew);
  2237. COleVariant var(lpszName, VT_BSTRT);
  2238. DAO_CHECK(m_pDAOQueryDef->put_Name(V_BSTR(&var)));
  2239. }
  2240. CString CDaoQueryDef::GetSQL()
  2241. {
  2242. ASSERT_VALID(this);
  2243. ASSERT(IsOpen());
  2244. COleVariant var;
  2245. DAO_CHECK(m_pDAOQueryDef->get_SQL(&V_BSTR(&var)));
  2246. var.vt = VT_BSTR;
  2247. return V_BSTRT(&var);
  2248. }
  2249. void CDaoQueryDef::SetSQL(LPCTSTR lpszSQL)
  2250. {
  2251. ASSERT_VALID(this);
  2252. ASSERT(IsOpen() || m_bNew);
  2253. COleVariant var(lpszSQL, VT_BSTRT);
  2254. DAO_CHECK(m_pDAOQueryDef->put_SQL(V_BSTR(&var)));
  2255. }
  2256. short CDaoQueryDef::GetType()
  2257. {
  2258. ASSERT_VALID(this);
  2259. ASSERT(IsOpen());
  2260. short nType;
  2261. DAO_CHECK(m_pDAOQueryDef->get_Type(&nType));
  2262. return nType;
  2263. }
  2264. COleDateTime CDaoQueryDef::GetDateCreated()
  2265. {
  2266. ASSERT_VALID(this);
  2267. ASSERT(IsOpen());
  2268. COleVariant varDate;
  2269. DAO_CHECK(m_pDAOQueryDef->get_DateCreated(&varDate));
  2270. return varDate.date;
  2271. }
  2272. COleDateTime CDaoQueryDef::GetDateLastUpdated()
  2273. {
  2274. ASSERT_VALID(this);
  2275. ASSERT(IsOpen());
  2276. COleVariant varDate;
  2277. DAO_CHECK(m_pDAOQueryDef->get_LastUpdated(&varDate));
  2278. return varDate.date;
  2279. }
  2280. CString CDaoQueryDef::GetConnect()
  2281. {
  2282. ASSERT_VALID(this);
  2283. ASSERT(IsOpen());
  2284. COleVariant var;
  2285. DAO_CHECK(m_pDAOQueryDef->get_Connect(&V_BSTR(&var)));
  2286. var.vt = VT_BSTR;
  2287. return V_BSTRT(&var);
  2288. }
  2289. void CDaoQueryDef::SetConnect(LPCTSTR lpszConnect)
  2290. {
  2291. ASSERT_VALID(this);
  2292. ASSERT(IsOpen() || m_bNew);
  2293. COleVariant var(lpszConnect, VT_BSTRT);
  2294. DAO_CHECK(m_pDAOQueryDef->put_Connect(V_BSTR(&var)));
  2295. }
  2296. short CDaoQueryDef::GetODBCTimeout()
  2297. {
  2298. ASSERT_VALID(this);
  2299. ASSERT(IsOpen());
  2300. short nTimeout;
  2301. DAO_CHECK(m_pDAOQueryDef->get_ODBCTimeout(&nTimeout));
  2302. return nTimeout;
  2303. }
  2304. void CDaoQueryDef::SetODBCTimeout(short nODBCTimeout)
  2305. {
  2306. ASSERT_VALID(this);
  2307. ASSERT(IsOpen() || m_bNew);
  2308. DAO_CHECK(m_pDAOQueryDef->put_ODBCTimeout(nODBCTimeout));
  2309. }
  2310. BOOL CDaoQueryDef::GetReturnsRecords()
  2311. {
  2312. ASSERT_VALID(this);
  2313. ASSERT(IsOpen());
  2314. short nReturnsRecords;
  2315. DAO_CHECK(m_pDAOQueryDef->get_ReturnsRecords(&nReturnsRecords));
  2316. return nReturnsRecords == AFX_DAO_TRUE;
  2317. }
  2318. void CDaoQueryDef::SetReturnsRecords(BOOL bReturnsRecords)
  2319. {
  2320. ASSERT_VALID(this);
  2321. ASSERT(IsOpen() || m_bNew);
  2322. DAO_CHECK(m_pDAOQueryDef->put_ReturnsRecords(
  2323. (short)(bReturnsRecords ? AFX_DAO_TRUE : AFX_DAO_FALSE)));
  2324. }
  2325. long CDaoQueryDef::GetRecordsAffected()
  2326. {
  2327. ASSERT_VALID(this);
  2328. ASSERT(IsOpen());
  2329. long lRecordsAffected;
  2330. DAO_CHECK(m_pDAOQueryDef->get_RecordsAffected(&lRecordsAffected));
  2331. return lRecordsAffected;
  2332. }
  2333. void CDaoQueryDef::Execute(int nOptions)
  2334. {
  2335. ASSERT_VALID(this);
  2336. ASSERT(m_pDAOQueryDef != NULL);
  2337. DAO_CHECK(m_pDAOQueryDef->Execute(COleVariant((long)nOptions)));
  2338. }
  2339. COleVariant CDaoQueryDef::GetParamValue(LPCTSTR lpszName)
  2340. {
  2341. ASSERT_VALID(this);
  2342. ASSERT(IsOpen());
  2343. ASSERT(m_pDAOQueryDef != NULL);
  2344. if (m_pDAOParameters == NULL)
  2345. InitParametersCollection();
  2346. DAOParameter* pDAOParameter = NULL;
  2347. COleVariant var;
  2348. TRY
  2349. {
  2350. DAO_CHECK(m_pDAOParameters->get_Item(
  2351. COleVariant(lpszName, VT_BSTRT), &pDAOParameter));
  2352. DAO_CHECK(pDAOParameter->get_Value(&var));
  2353. }
  2354. CATCH_ALL(e)
  2355. {
  2356. if (pDAOParameter != NULL)
  2357. pDAOParameter->Release();
  2358. THROW_LAST();
  2359. }
  2360. END_CATCH_ALL
  2361. pDAOParameter->Release();
  2362. return var;
  2363. }
  2364. COleVariant CDaoQueryDef::GetParamValue(int nIndex)
  2365. {
  2366. ASSERT_VALID(this);
  2367. ASSERT(IsOpen());
  2368. ASSERT(m_pDAOQueryDef != NULL);
  2369. if (m_pDAOParameters == NULL)
  2370. InitParametersCollection();
  2371. DAOParameter* pDAOParameter = NULL;
  2372. COleVariant var;
  2373. TRY
  2374. {
  2375. DAO_CHECK(m_pDAOParameters->get_Item(
  2376. COleVariant((long)nIndex), &pDAOParameter));
  2377. DAO_CHECK(pDAOParameter->get_Value(&var));
  2378. }
  2379. CATCH_ALL(e)
  2380. {
  2381. if (pDAOParameter != NULL)
  2382. pDAOParameter->Release();
  2383. THROW_LAST();
  2384. }
  2385. END_CATCH_ALL
  2386. pDAOParameter->Release();
  2387. return var;
  2388. }
  2389. void CDaoQueryDef::SetParamValue(LPCTSTR lpszName,
  2390. const COleVariant& varValue)
  2391. {
  2392. ASSERT_VALID(this);
  2393. ASSERT(IsOpen() || m_bNew);
  2394. ASSERT(m_pDAOQueryDef != NULL);
  2395. if (m_pDAOParameters == NULL)
  2396. InitParametersCollection();
  2397. DAOParameter* pDAOParameter = NULL;
  2398. TRY
  2399. {
  2400. DAO_CHECK(m_pDAOParameters->get_Item(
  2401. COleVariant(lpszName, VT_BSTRT), &pDAOParameter));
  2402. DAO_CHECK(pDAOParameter->put_Value(varValue));
  2403. }
  2404. CATCH_ALL(e)
  2405. {
  2406. if (pDAOParameter != NULL)
  2407. pDAOParameter->Release();
  2408. THROW_LAST();
  2409. }
  2410. END_CATCH_ALL
  2411. pDAOParameter->Release();
  2412. }
  2413. void CDaoQueryDef::SetParamValue(int nIndex,
  2414. const COleVariant& varValue)
  2415. {
  2416. ASSERT_VALID(this);
  2417. ASSERT(IsOpen() || m_bNew);
  2418. ASSERT(m_pDAOQueryDef != NULL);
  2419. if (m_pDAOParameters == NULL)
  2420. InitParametersCollection();
  2421. DAOParameter* pDAOParameter = NULL;
  2422. TRY
  2423. {
  2424. DAO_CHECK(m_pDAOParameters->get_Item(
  2425. COleVariant((long)nIndex), &pDAOParameter));
  2426. DAO_CHECK(pDAOParameter->put_Value(varValue));
  2427. }
  2428. CATCH_ALL(e)
  2429. {
  2430. if (pDAOParameter != NULL)
  2431. pDAOParameter->Release();
  2432. THROW_LAST();
  2433. }
  2434. END_CATCH_ALL
  2435. pDAOParameter->Release();
  2436. }
  2437. void CDaoQueryDef::SetParamValueNull(LPCTSTR lpszName)
  2438. {
  2439. ASSERT_VALID(this);
  2440. SetParamValue(lpszName, _afxNullVariant);
  2441. }
  2442. void CDaoQueryDef::SetParamValueNull(int nIndex)
  2443. {
  2444. ASSERT_VALID(this);
  2445. SetParamValue(nIndex, _afxNullVariant);
  2446. }
  2447. short CDaoQueryDef::GetFieldCount()
  2448. {
  2449. ASSERT_VALID(this);
  2450. short nFields;
  2451. if (m_pDAOFields == NULL)
  2452. InitFieldsCollection();
  2453. DAO_CHECK(m_pDAOFields->get_Count(&nFields));
  2454. return nFields;
  2455. }
  2456. void CDaoQueryDef::GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
  2457. DWORD dwInfoOptions)
  2458. {
  2459. ASSERT_VALID(this);
  2460. if (m_pDAOFields == NULL)
  2461. InitFieldsCollection();
  2462. // Get DAOField object and fill in field info struct
  2463. DAOField* pDAOField;
  2464. DAO_CHECK(m_pDAOFields->get_Item(
  2465. COleVariant((long)nIndex), &pDAOField));
  2466. AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
  2467. // Clean up
  2468. pDAOField->Release();
  2469. }
  2470. void CDaoQueryDef::GetFieldInfo(LPCTSTR lpszName,
  2471. CDaoFieldInfo& fieldinfo, DWORD dwInfoOptions)
  2472. {
  2473. ASSERT_VALID(this);
  2474. if (m_pDAOFields == NULL)
  2475. InitFieldsCollection();
  2476. // Get DAOField object and fill in field info struct
  2477. DAOField* pDAOField;
  2478. DAO_CHECK(m_pDAOFields->get_Item(
  2479. COleVariant(lpszName, VT_BSTRT), &pDAOField));
  2480. AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
  2481. // Clean up
  2482. pDAOField->Release();
  2483. }
  2484. short CDaoQueryDef::GetParameterCount()
  2485. {
  2486. ASSERT_VALID(this);
  2487. short nParameters;
  2488. if (m_pDAOParameters == NULL)
  2489. InitParametersCollection();
  2490. DAO_CHECK(m_pDAOParameters->get_Count(&nParameters));
  2491. return nParameters;
  2492. }
  2493. void CDaoQueryDef::GetParameterInfo(int nIndex,
  2494. CDaoParameterInfo& paraminfo, DWORD dwInfoOptions)
  2495. {
  2496. ASSERT_VALID(this);
  2497. if (m_pDAOParameters == NULL)
  2498. InitParametersCollection();
  2499. // Get DAOParameter object and fill in parameter info struct
  2500. DAOParameter* pDAOParameter;
  2501. DAO_CHECK(m_pDAOParameters->get_Item(
  2502. COleVariant((long)nIndex), &pDAOParameter));
  2503. FillParameterInfo(pDAOParameter, paraminfo, dwInfoOptions);
  2504. // Clean up
  2505. pDAOParameter->Release();
  2506. }
  2507. void CDaoQueryDef::GetParameterInfo(LPCTSTR lpszName,
  2508. CDaoParameterInfo& paraminfo, DWORD dwInfoOptions)
  2509. {
  2510. ASSERT_VALID(this);
  2511. if (m_pDAOParameters == NULL)
  2512. InitParametersCollection();
  2513. // Get DAOParameter object and fill in parameter info struct
  2514. DAOParameter* pDAOParameter;
  2515. DAO_CHECK(m_pDAOParameters->get_Item(
  2516. COleVariant(lpszName, VT_BSTRT), &pDAOParameter));
  2517. FillParameterInfo(pDAOParameter, paraminfo, dwInfoOptions);
  2518. // Clean up
  2519. pDAOParameter->Release();
  2520. }
  2521. //Implementation functions
  2522. void CDaoQueryDef::InitFieldsCollection()
  2523. {
  2524. ASSERT_VALID(this);
  2525. DAO_CHECK(m_pDAOQueryDef->get_Fields(&m_pDAOFields));
  2526. }
  2527. void CDaoQueryDef::InitParametersCollection()
  2528. {
  2529. ASSERT_VALID(this);
  2530. DAO_CHECK(m_pDAOQueryDef->get_Parameters(&m_pDAOParameters));
  2531. }
  2532. void CDaoQueryDef::FillParameterInfo(DAOParameter* pDAOParameter,
  2533. CDaoParameterInfo& paraminfo, DWORD dwOptions)
  2534. {
  2535. ASSERT_VALID(this);
  2536. ASSERT(pDAOParameter != NULL);
  2537. ASSERT(dwOptions != NULL);
  2538. COleVariant var;
  2539. if (dwOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  2540. {
  2541. // All parameter info is basic info
  2542. DAO_CHECK(pDAOParameter->get_Name(&V_BSTR(&var)));
  2543. var.vt = VT_BSTR;
  2544. paraminfo.m_strName = V_BSTRT(&var);
  2545. var.Clear();
  2546. TCHAR* pch = paraminfo.m_strName.GetBuffer(0);
  2547. int nLength = lstrlen(pch);
  2548. if (nLength > 0 && *pch == '[' && *(pch + nLength -1) == ']')
  2549. {
  2550. *(pch + nLength - 1) = 0; // remove last bracket.
  2551. lstrcpy(pch, pch + 1);
  2552. }
  2553. paraminfo.m_strName.ReleaseBuffer(-1);
  2554. DAO_CHECK(pDAOParameter->get_Type(
  2555. &paraminfo.m_nType));
  2556. DAO_CHECK(pDAOParameter->get_Value(
  2557. &paraminfo.m_varValue));
  2558. }
  2559. }
  2560. void CDaoQueryDef::ThrowDaoException(int nAfxDaoError)
  2561. {
  2562. ASSERT_VALID(this);
  2563. AfxThrowDaoException(nAfxDaoError);
  2564. }
  2565. #ifdef _DEBUG
  2566. void CDaoQueryDef::AssertValid() const
  2567. {
  2568. CObject::AssertValid();
  2569. }
  2570. void CDaoQueryDef::Dump(CDumpContext& dc) const
  2571. {
  2572. ASSERT_VALID(this);
  2573. CObject::Dump(dc);
  2574. dc << "m_bOpen = " << m_bOpen;
  2575. dc << "\nm_bNew = " << m_bNew;
  2576. dc << "\n";
  2577. }
  2578. #endif //_DEBUG
  2579. //////////////////////////////////////////////////////////////////////////
  2580. // CDaoRecordset
  2581. IMPLEMENT_DYNAMIC(CDaoRecordset, CObject )
  2582. CDaoRecordset::CDaoRecordset(CDaoDatabase* pDatabase)
  2583. {
  2584. m_bOpen = FALSE;
  2585. m_pMapFieldCache = NULL;
  2586. m_pMapFieldIndex = NULL;
  2587. m_bCheckCacheForDirtyFields = TRUE;
  2588. m_prgDaoColBindInfo = NULL;
  2589. m_pulColumnLengths = NULL;
  2590. m_pbFieldFlags = NULL;
  2591. m_pbParamFlags = NULL;
  2592. m_pDAORecordset = NULL;
  2593. m_pICDAORecordsetGetRows = NULL;
  2594. m_pQueryDef = NULL;
  2595. m_pTableDef = NULL;
  2596. m_pDAOFields = NULL;
  2597. m_pDAOIndexes = NULL;
  2598. m_pDatabase = pDatabase;
  2599. m_nDefaultType = dbOpenDynaset;
  2600. m_nStatus = 0;
  2601. m_nFields = 0;
  2602. m_nParams = 0;
  2603. }
  2604. CDaoRecordset::~CDaoRecordset()
  2605. {
  2606. if (IsOpen())
  2607. Close();
  2608. // Clean up database if necessary
  2609. if (m_pDatabase != NULL && (m_nStatus & AFX_DAO_IMPLICIT_DB))
  2610. {
  2611. m_pDatabase->Close();
  2612. delete m_pDatabase;
  2613. m_pDatabase = NULL;
  2614. }
  2615. }
  2616. void CDaoRecordset::Open(int nOpenType, LPCTSTR lpszSQL, int nOptions)
  2617. {
  2618. ASSERT_VALID(this);
  2619. ASSERT(nOpenType == AFX_DAO_USE_DEFAULT_TYPE ||
  2620. nOpenType == dbOpenDynaset || nOpenType == dbOpenSnapshot ||
  2621. nOpenType == dbOpenTable);
  2622. // Re-Opening is invalid.
  2623. if (IsOpen())
  2624. {
  2625. ASSERT(FALSE);
  2626. return;
  2627. }
  2628. if (nOpenType == AFX_DAO_USE_DEFAULT_TYPE)
  2629. m_nOpenType = m_nDefaultType;
  2630. else
  2631. m_nOpenType = nOpenType;
  2632. // Snapshots readOnly in DAO model.
  2633. if (m_nOpenType == dbOpenSnapshot)
  2634. nOptions |= dbReadOnly;
  2635. // Cache parameters and initialize
  2636. m_nOptions = nOptions;
  2637. m_cbFixedLengthFields = 0;
  2638. // Cache information for use in Requery
  2639. m_strRequerySQL = lpszSQL;
  2640. m_strRequeryFilter = m_strFilter;
  2641. m_strRequerySort = m_strSort;
  2642. AllocDatabase();
  2643. m_strSQL = lpszSQL;
  2644. if (m_strSQL.IsEmpty())
  2645. m_strSQL = GetDefaultSQL();
  2646. // Open table directly if option specified
  2647. if (m_nOpenType == dbOpenTable)
  2648. {
  2649. m_pTableDef = new CDaoTableDef(m_pDatabase);
  2650. m_nStatus |= AFX_DAO_IMPLICIT_TD;
  2651. TRY
  2652. {
  2653. // Must remove the bracket from the name
  2654. StripBrackets(m_strSQL, m_strSQL.GetBuffer(0));
  2655. m_strSQL.ReleaseBuffer();
  2656. m_pTableDef->Open(m_strSQL);
  2657. // Open the DAO recordset (implicit MoveFirst)
  2658. DAO_CHECK(m_pTableDef->m_pDAOTableDef->OpenRecordset(
  2659. COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
  2660. &m_pDAORecordset));
  2661. }
  2662. CATCH_ALL(e)
  2663. {
  2664. // Once recordset marked as open, Close handles this
  2665. if (m_pTableDef->IsOpen())
  2666. m_pTableDef->Close();
  2667. delete m_pTableDef;
  2668. THROW_LAST();
  2669. }
  2670. END_CATCH_ALL
  2671. }
  2672. else
  2673. {
  2674. m_pQueryDef = new CDaoQueryDef(m_pDatabase);
  2675. m_nStatus |= AFX_DAO_IMPLICIT_QD;
  2676. TRY
  2677. {
  2678. // If initial clause includes potential start of row returning
  2679. // query, then SQL passed to Open must be valid
  2680. // (Note: TABLE is valid for UNION-type queries)
  2681. if ((_tcsnicmp(m_strSQL, _afxSelect2, _countof(_afxSelect2)-1) != 0) &&
  2682. (_tcsnicmp(m_strSQL, _afxParameters2, _countof(_afxParameters2)-1) != 0) &&
  2683. (_tcsnicmp(m_strSQL, _afxTransform2, _countof(_afxTransform2)-1) != 0) &&
  2684. (_tcsnicmp(m_strSQL, _afxTable2, _countof(_afxTable2)-1) != 0))
  2685. {
  2686. BuildSQL();
  2687. }
  2688. else
  2689. {
  2690. // Add the filter and sort
  2691. if (!m_strFilter.IsEmpty())
  2692. m_strSQL += _afxWhere2 + m_strFilter;
  2693. if (!m_strSort.IsEmpty())
  2694. m_strSQL += _afxOrderBy2 + m_strSort;
  2695. }
  2696. // Create and define temp query
  2697. m_pQueryDef->Open();
  2698. m_pQueryDef->SetSQL(m_strSQL);
  2699. BindParameters();
  2700. // Open the DAO recordset (implicit MoveFirst)
  2701. DAO_CHECK(m_pQueryDef->m_pDAOQueryDef->_30_OpenRecordset(
  2702. COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
  2703. &m_pDAORecordset));
  2704. }
  2705. CATCH_ALL(e)
  2706. {
  2707. // Once recordset marked as open, Close handles this
  2708. if (m_pQueryDef->IsOpen())
  2709. m_pQueryDef->Close();
  2710. delete m_pQueryDef;
  2711. THROW_LAST();
  2712. }
  2713. END_CATCH_ALL
  2714. }
  2715. m_bOpen = TRUE;
  2716. // Add the recordset to map of Open CDaoRecordsets
  2717. m_pDatabase->m_mapRecordsets.SetAt(this, this);
  2718. TRY
  2719. {
  2720. BindFields();
  2721. GetDataAndFixupNulls();
  2722. SetCursorAttributes();
  2723. }
  2724. CATCH_ALL(e)
  2725. {
  2726. Close();
  2727. THROW_LAST();
  2728. }
  2729. END_CATCH_ALL
  2730. }
  2731. void CDaoRecordset::Open(CDaoQueryDef* pQueryDef, int nOpenType,
  2732. int nOptions)
  2733. {
  2734. ASSERT_VALID(this);
  2735. // Must pass valid, open QueryDef
  2736. ASSERT(pQueryDef != NULL);
  2737. if (!pQueryDef->IsOpen())
  2738. ThrowDaoException(AFX_DAO_ERROR_OBJECT_NOT_OPEN);
  2739. // Re-Opening is invalid.
  2740. if (IsOpen())
  2741. {
  2742. ASSERT(FALSE);
  2743. return;
  2744. }
  2745. if (nOpenType == AFX_DAO_USE_DEFAULT_TYPE)
  2746. m_nOpenType = m_nDefaultType;
  2747. else
  2748. m_nOpenType = nOpenType;
  2749. // Can't open table type recordsets with QueryDef
  2750. ASSERT(m_nOpenType == dbOpenDynaset || m_nOpenType == dbOpenSnapshot);
  2751. // Snapshots readOnly in DAO model.
  2752. if (m_nOpenType == dbOpenSnapshot)
  2753. nOptions |= dbReadOnly;
  2754. // Cache parameters and initialize
  2755. m_nOptions = nOptions;
  2756. m_cbFixedLengthFields = 0;
  2757. // Use pre-defined query
  2758. m_pQueryDef = pQueryDef;
  2759. // Share the same database object
  2760. m_pDatabase = m_pQueryDef->m_pDatabase;
  2761. BindParameters();
  2762. // Open the DAO recordset (implicit MoveFirst)
  2763. DAO_CHECK(m_pQueryDef->m_pDAOQueryDef->_30_OpenRecordset(
  2764. COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
  2765. &m_pDAORecordset));
  2766. m_bOpen = TRUE;
  2767. // Add the recordset to map of Open CDaoRecordsets
  2768. m_pDatabase->m_mapRecordsets.SetAt(this, this);
  2769. TRY
  2770. {
  2771. BindFields();
  2772. GetDataAndFixupNulls();
  2773. SetCursorAttributes();
  2774. }
  2775. CATCH_ALL(e)
  2776. {
  2777. Close();
  2778. THROW_LAST();
  2779. }
  2780. END_CATCH_ALL
  2781. }
  2782. void CDaoRecordset::Open(CDaoTableDef* pTableDef, int nOpenType,
  2783. int nOptions)
  2784. {
  2785. ASSERT_VALID(this);
  2786. // Must pass valid, open TableDef
  2787. ASSERT(pTableDef != NULL);
  2788. if (!pTableDef->IsOpen())
  2789. ThrowDaoException(AFX_DAO_ERROR_OBJECT_NOT_OPEN);
  2790. m_pTableDef = pTableDef;
  2791. // Re-Opening is invalid.
  2792. if (IsOpen())
  2793. {
  2794. ASSERT(FALSE);
  2795. return;
  2796. }
  2797. if (nOpenType == AFX_DAO_USE_DEFAULT_TYPE)
  2798. m_nOpenType = m_nDefaultType;
  2799. else
  2800. m_nOpenType = nOpenType;
  2801. // Cache parameters and initialize
  2802. m_nOptions = nOptions;
  2803. m_cbFixedLengthFields = 0;
  2804. // Share the same database object
  2805. m_pDatabase = m_pTableDef->m_pDatabase;
  2806. // Open the DAO recordset (implicit MoveFirst)
  2807. DAO_CHECK(m_pTableDef->m_pDAOTableDef->OpenRecordset(
  2808. COleVariant((long)m_nOpenType), COleVariant((long)m_nOptions),
  2809. &m_pDAORecordset));
  2810. m_bOpen = TRUE;
  2811. // Add the recordset to map of Open CDaoRecordsets
  2812. m_pDatabase->m_mapRecordsets.SetAt(this, this);
  2813. TRY
  2814. {
  2815. BindFields();
  2816. GetDataAndFixupNulls();
  2817. SetCursorAttributes();
  2818. }
  2819. CATCH_ALL(e)
  2820. {
  2821. Close();
  2822. THROW_LAST();
  2823. }
  2824. END_CATCH_ALL
  2825. }
  2826. void CDaoRecordset::Close()
  2827. {
  2828. ASSERT_VALID(this);
  2829. if (IsOpen())
  2830. FreeCache();
  2831. // Clean up name strings in ColBindInfo struct
  2832. if (m_prgDaoColBindInfo != NULL)
  2833. {
  2834. for (int nIndex = 0; nIndex < m_nFields; nIndex++)
  2835. {
  2836. #ifndef _UNICODE
  2837. delete[] (LPTSTR)m_prgDaoColBindInfo[nIndex].columnID.lpstr;
  2838. m_prgDaoColBindInfo[nIndex].columnID.lpstr = NULL;
  2839. #else
  2840. delete[] (LPTSTR)m_prgDaoColBindInfo[nIndex].columnID.lpwstr;
  2841. m_prgDaoColBindInfo[nIndex].columnID.lpwstr = NULL;
  2842. #endif
  2843. }
  2844. }
  2845. delete[] m_prgDaoColBindInfo;
  2846. m_prgDaoColBindInfo = NULL;
  2847. delete[] m_pulColumnLengths;
  2848. m_pulColumnLengths = NULL;
  2849. delete[] m_pbFieldFlags;
  2850. m_pbFieldFlags = NULL;
  2851. if (m_pMapFieldIndex != NULL)
  2852. {
  2853. delete m_pMapFieldIndex;
  2854. m_pMapFieldIndex = NULL;
  2855. }
  2856. if (m_pDAOIndexes != NULL)
  2857. {
  2858. m_pDAOIndexes->Release();
  2859. m_pDAOIndexes = NULL;
  2860. }
  2861. if (m_pDAOFields != NULL)
  2862. {
  2863. m_pDAOFields->Release();
  2864. m_pDAOFields = NULL;
  2865. }
  2866. if (m_pICDAORecordsetGetRows != NULL)
  2867. {
  2868. m_pICDAORecordsetGetRows->Release();
  2869. m_pICDAORecordsetGetRows = NULL;
  2870. }
  2871. if (m_pDAORecordset != NULL)
  2872. {
  2873. DAO_TRACE(m_pDAORecordset->Close());
  2874. m_pDAORecordset->Release();
  2875. m_pDAORecordset = NULL;
  2876. }
  2877. // Cleanup TableDef if not user supplied
  2878. if (m_pTableDef != NULL && m_nStatus & AFX_DAO_IMPLICIT_TD)
  2879. {
  2880. m_pTableDef->Close();
  2881. delete m_pTableDef;
  2882. m_pTableDef = NULL;
  2883. }
  2884. // Cleanup QueryDef if not user supplied
  2885. if (m_pQueryDef != NULL && m_nStatus & AFX_DAO_IMPLICIT_QD)
  2886. {
  2887. m_pQueryDef->Close();
  2888. delete m_pQueryDef;
  2889. m_pQueryDef = NULL;
  2890. }
  2891. m_nStatus &= ~AFX_DAO_IMPLICIT_QD;
  2892. m_nStatus &= ~AFX_DAO_IMPLICIT_TD;
  2893. m_pQueryDef = NULL;
  2894. m_pTableDef = NULL;
  2895. m_bOpen = FALSE;
  2896. // Remove the recordset from the CDaoDatabase's map
  2897. m_pDatabase->m_mapRecordsets.RemoveKey(this);
  2898. }
  2899. void CDaoRecordset::Requery()
  2900. {
  2901. ASSERT_VALID(this);
  2902. ASSERT(IsOpen());
  2903. ASSERT(CanRestart());
  2904. // If filter or sort strings changed, must Close and Open
  2905. // This is only effective if m_strFilter/m_strSort used
  2906. if ((m_pQueryDef != NULL &&
  2907. (m_nStatus & AFX_DAO_IMPLICIT_QD)) &&
  2908. ((m_strRequeryFilter != m_strFilter) ||
  2909. (m_strRequerySort != m_strSort)))
  2910. {
  2911. Close();
  2912. Open(m_nOpenType, m_strRequerySQL, m_nOptions);
  2913. }
  2914. else
  2915. {
  2916. // Rebind parameters in case values have changed
  2917. BindParameters();
  2918. if (m_pQueryDef != NULL)
  2919. {
  2920. COleVariant varDisp;
  2921. varDisp.pdispVal = m_pQueryDef->m_pDAOQueryDef;
  2922. varDisp.vt = VT_DISPATCH;
  2923. TRY
  2924. {
  2925. DAO_CHECK(m_pDAORecordset->Requery(varDisp));
  2926. }
  2927. CATCH_ALL(e)
  2928. {
  2929. // Reset vt to prevent release of DAOQueryDef
  2930. varDisp.vt = VT_EMPTY;
  2931. THROW_LAST();
  2932. }
  2933. END_CATCH_ALL
  2934. // Reset vt to prevent release of DAOQueryDef
  2935. varDisp.vt = VT_EMPTY;
  2936. }
  2937. else
  2938. // Must be a table type recordset (this will fail!)
  2939. DAO_CHECK(m_pDAORecordset->Requery(_afxOptionalVariant));
  2940. GetDataAndFixupNulls();
  2941. }
  2942. }
  2943. CString CDaoRecordset::GetDefaultDBName()
  2944. {
  2945. ASSERT_VALID(this);
  2946. // Override and add UNC path to .MDB file
  2947. return _T("");
  2948. }
  2949. CString CDaoRecordset::GetDefaultSQL()
  2950. {
  2951. ASSERT_VALID(this);
  2952. // Override and add table name or entire SQL SELECT statement
  2953. return _T("");
  2954. }
  2955. void CDaoRecordset::DoFieldExchange(CDaoFieldExchange* /* pFX */)
  2956. {
  2957. ASSERT_VALID(this);
  2958. // Do nothing if dynamic binding, otherwise override and add DFX calls
  2959. }
  2960. BOOL CDaoRecordset::IsBOF() const
  2961. {
  2962. ASSERT_VALID(this);
  2963. ASSERT(IsOpen());
  2964. short nBOF;
  2965. DAO_CHECK(m_pDAORecordset->get_BOF(&nBOF));
  2966. return nBOF == AFX_DAO_TRUE;
  2967. }
  2968. BOOL CDaoRecordset::IsEOF() const
  2969. {
  2970. ASSERT_VALID(this);
  2971. ASSERT(IsOpen());
  2972. short nEOF;
  2973. DAO_CHECK(m_pDAORecordset->get_EOF(&nEOF));
  2974. return nEOF == AFX_DAO_TRUE;
  2975. }
  2976. BOOL CDaoRecordset::IsDeleted() const
  2977. {
  2978. ASSERT_VALID(this);
  2979. ASSERT(IsOpen());
  2980. return m_bDeleted;
  2981. }
  2982. BOOL CDaoRecordset::CanScroll() const
  2983. {
  2984. ASSERT_VALID(this);
  2985. ASSERT(IsOpen());
  2986. return m_bScrollable;
  2987. }
  2988. BOOL CDaoRecordset::CanUpdate() const
  2989. {
  2990. ASSERT_VALID(this);
  2991. ASSERT(IsOpen());
  2992. short nUpdatable;
  2993. DAO_CHECK(m_pDAORecordset->get_Updatable(&nUpdatable));
  2994. return nUpdatable == AFX_DAO_TRUE;
  2995. }
  2996. BOOL CDaoRecordset::CanAppend() const
  2997. {
  2998. ASSERT_VALID(this);
  2999. ASSERT(IsOpen());
  3000. return m_bAppendable;
  3001. }
  3002. BOOL CDaoRecordset::CanRestart()
  3003. {
  3004. ASSERT_VALID(this);
  3005. ASSERT(IsOpen());
  3006. ASSERT(m_pDAORecordset != NULL);
  3007. short nRestartable;
  3008. DAO_CHECK(m_pDAORecordset->get_Restartable(&nRestartable));
  3009. return nRestartable == AFX_DAO_TRUE;
  3010. }
  3011. BOOL CDaoRecordset::CanTransact()
  3012. {
  3013. ASSERT_VALID(this);
  3014. ASSERT(IsOpen());
  3015. short nTransactions;
  3016. DAO_CHECK(m_pDAORecordset->get_Transactions(&nTransactions));
  3017. return nTransactions == AFX_DAO_TRUE;
  3018. }
  3019. BOOL CDaoRecordset::CanBookmark()
  3020. {
  3021. ASSERT_VALID(this);
  3022. ASSERT(IsOpen());
  3023. short nBookmarkable;
  3024. DAO_CHECK(m_pDAORecordset->get_Bookmarkable(&nBookmarkable));
  3025. return nBookmarkable == AFX_DAO_TRUE;
  3026. }
  3027. CString CDaoRecordset::GetName()
  3028. {
  3029. ASSERT_VALID(this);
  3030. ASSERT(IsOpen());
  3031. ASSERT(m_pDAORecordset != NULL);
  3032. COleVariant var;
  3033. DAO_CHECK(m_pDAORecordset->get_Name(&V_BSTR(&var)));
  3034. var.vt = VT_BSTR;
  3035. return V_BSTRT(&var);
  3036. }
  3037. short CDaoRecordset::GetType()
  3038. {
  3039. ASSERT_VALID(this);
  3040. ASSERT(IsOpen());
  3041. ASSERT(m_pDAORecordset != NULL);
  3042. short nType;
  3043. DAO_CHECK(m_pDAORecordset->get_Type(&nType));
  3044. return nType;
  3045. }
  3046. short CDaoRecordset::GetEditMode()
  3047. {
  3048. ASSERT_VALID(this);
  3049. ASSERT(IsOpen());
  3050. ASSERT(m_pDAORecordset != NULL);
  3051. short nEditMode;
  3052. DAO_CHECK(m_pDAORecordset->get_EditMode(&nEditMode));
  3053. return nEditMode;
  3054. }
  3055. CString CDaoRecordset::GetSQL() const
  3056. {
  3057. ASSERT_VALID(this);
  3058. ASSERT(IsOpen());
  3059. ASSERT(m_pDAORecordset != NULL);
  3060. return m_strSQL;
  3061. }
  3062. COleDateTime CDaoRecordset::GetDateCreated()
  3063. {
  3064. ASSERT_VALID(this);
  3065. ASSERT(IsOpen());
  3066. ASSERT(m_pDAORecordset != NULL);
  3067. COleVariant varDate;
  3068. DAO_CHECK(m_pDAORecordset->get_DateCreated(&varDate));
  3069. return varDate.date;
  3070. }
  3071. COleDateTime CDaoRecordset::GetDateLastUpdated()
  3072. {
  3073. ASSERT_VALID(this);
  3074. ASSERT(IsOpen());
  3075. ASSERT(m_pDAORecordset != NULL);
  3076. COleVariant varDate;
  3077. DAO_CHECK(m_pDAORecordset->get_LastUpdated(&varDate));
  3078. return varDate.date;
  3079. }
  3080. COleVariant CDaoRecordset::GetLastModifiedBookmark()
  3081. {
  3082. ASSERT_VALID(this);
  3083. ASSERT(IsOpen());
  3084. ASSERT(m_pDAORecordset != NULL);
  3085. COleVariant var;
  3086. DAO_CHECK(m_pDAORecordset->get_LastModified(&var.parray));
  3087. var.vt = VT_ARRAY | VT_UI1;
  3088. return var;
  3089. }
  3090. CString CDaoRecordset::GetValidationRule()
  3091. {
  3092. ASSERT_VALID(this);
  3093. ASSERT(IsOpen());
  3094. ASSERT(m_pDAORecordset != NULL);
  3095. COleVariant var;
  3096. DAO_CHECK(m_pDAORecordset->get_ValidationRule(&V_BSTR(&var)));
  3097. var.vt = VT_BSTR;
  3098. return V_BSTRT(&var);
  3099. }
  3100. CString CDaoRecordset::GetValidationText()
  3101. {
  3102. ASSERT_VALID(this);
  3103. ASSERT(IsOpen());
  3104. ASSERT(m_pDAORecordset != NULL);
  3105. COleVariant var;
  3106. DAO_CHECK(m_pDAORecordset->get_ValidationText(&V_BSTR(&var)));
  3107. var.vt = VT_BSTR;
  3108. return V_BSTRT(&var);
  3109. }
  3110. CString CDaoRecordset::GetCurrentIndex()
  3111. {
  3112. ASSERT_VALID(this);
  3113. ASSERT(IsOpen());
  3114. ASSERT(m_pDAORecordset != NULL);
  3115. COleVariant var;
  3116. DAO_CHECK(m_pDAORecordset->get_Index(&V_BSTR(&var)));
  3117. var.vt = VT_BSTR;
  3118. return V_BSTRT(&var);
  3119. }
  3120. void CDaoRecordset::SetCurrentIndex(LPCTSTR lpszName)
  3121. {
  3122. ASSERT_VALID(this);
  3123. ASSERT(IsOpen());
  3124. ASSERT(m_pDAORecordset != NULL);
  3125. COleVariant var(lpszName, VT_BSTRT);
  3126. DAO_CHECK(m_pDAORecordset->put_Index(V_BSTR(&var)));
  3127. // Refetch the data
  3128. GetDataAndFixupNulls();
  3129. }
  3130. long CDaoRecordset::GetRecordCount()
  3131. {
  3132. ASSERT_VALID(this);
  3133. ASSERT(IsOpen());
  3134. ASSERT(m_pDAORecordset != NULL);
  3135. long lRecordCount;
  3136. DAO_CHECK(m_pDAORecordset->get_RecordCount(&lRecordCount));
  3137. return lRecordCount;
  3138. }
  3139. void CDaoRecordset::SetFieldDirty(void* pv, BOOL bDirty)
  3140. {
  3141. ASSERT_VALID(this);
  3142. if (m_nFields <= 0)
  3143. {
  3144. // Can't set fields dirty if no bound fields
  3145. ASSERT(FALSE);
  3146. return;
  3147. }
  3148. int nIndex = 0, nIndexEnd;
  3149. if (pv == NULL)
  3150. nIndexEnd = m_nFields - 1;
  3151. else
  3152. {
  3153. nIndex = nIndexEnd = GetFieldIndex(pv);
  3154. ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
  3155. }
  3156. while (nIndex <= nIndexEnd)
  3157. {
  3158. if (bDirty)
  3159. SetDirtyFieldStatus(nIndex);
  3160. else
  3161. ClearDirtyFieldStatus(nIndex);
  3162. nIndex++;
  3163. }
  3164. }
  3165. BOOL CDaoRecordset::IsFieldDirty(void* pv)
  3166. {
  3167. ASSERT_VALID(this);
  3168. short nEditMode = GetEditMode();
  3169. // Fields can't be dirty if not in edit/addnew mode or no fields bound
  3170. if (nEditMode == dbEditNone || m_nFields <= 0)
  3171. return FALSE;
  3172. // Check if cache field values have changed and mark as dirty
  3173. if (m_bCheckCacheForDirtyFields)
  3174. {
  3175. if (nEditMode == dbEditInProgress)
  3176. MarkForEdit();
  3177. else
  3178. MarkForAddNew();
  3179. }
  3180. int nIndex = 0, nIndexEnd;
  3181. if (pv == NULL)
  3182. nIndexEnd = m_nFields - 1;
  3183. else
  3184. {
  3185. // Get the field index to use status array
  3186. nIndex = nIndexEnd = GetFieldIndex(pv);
  3187. ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
  3188. }
  3189. BOOL bDirty = FALSE;
  3190. while (nIndex <= nIndexEnd && !bDirty)
  3191. bDirty = IsFieldStatusDirty(nIndex++);
  3192. return bDirty;
  3193. }
  3194. void CDaoRecordset::SetFieldNull(void* pv, BOOL bNull)
  3195. {
  3196. ASSERT_VALID(this);
  3197. if (m_nFields <= 0)
  3198. {
  3199. ASSERT(FALSE);
  3200. return;
  3201. }
  3202. if (bNull)
  3203. {
  3204. // Need field exchange to set value to PSEUDO NULL.
  3205. CDaoFieldExchange fx(CDaoFieldExchange::SetFieldNull, this, pv);
  3206. fx.m_nFieldFound = 0;
  3207. DoFieldExchange(&fx);
  3208. // If no field found, index will still be zero
  3209. ASSERT(fx.m_nFieldFound != 0);
  3210. }
  3211. else
  3212. {
  3213. // Set status array not NULL. Don't need field exchange mechanism.
  3214. int nIndex = 0, nIndexEnd;
  3215. if (pv == NULL)
  3216. nIndexEnd = m_nFields - 1;
  3217. else
  3218. {
  3219. nIndex = nIndexEnd = GetFieldIndex(pv);
  3220. ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
  3221. }
  3222. while (nIndex <= nIndexEnd)
  3223. {
  3224. ClearNullFieldStatus(nIndex);
  3225. nIndex++;
  3226. }
  3227. }
  3228. }
  3229. BOOL CDaoRecordset::IsFieldNull(void* pv)
  3230. {
  3231. ASSERT_VALID(this);
  3232. if (m_nFields <= 0)
  3233. {
  3234. ASSERT(FALSE);
  3235. return FALSE;
  3236. }
  3237. int nIndex = 0, nIndexEnd;
  3238. if (pv == NULL)
  3239. nIndexEnd = m_nFields - 1;
  3240. else
  3241. {
  3242. // Get the field index to use status array
  3243. nIndex = nIndexEnd = GetFieldIndex(pv);
  3244. ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
  3245. }
  3246. BOOL bNull = FALSE;
  3247. while (nIndex <= nIndexEnd && !bNull)
  3248. bNull = IsFieldStatusNull(nIndex++);
  3249. return bNull;
  3250. }
  3251. BOOL CDaoRecordset::IsFieldNullable(void* pv)
  3252. {
  3253. ASSERT_VALID(this);
  3254. if (m_nFields <= 0)
  3255. {
  3256. ASSERT(FALSE);
  3257. return FALSE;
  3258. }
  3259. int nIndex = 0, nIndexEnd;
  3260. if (pv == NULL)
  3261. nIndexEnd = m_nFields - 1;
  3262. else
  3263. {
  3264. // Get the field index to use status array
  3265. nIndex = nIndexEnd = GetFieldIndex(pv);
  3266. ASSERT(nIndex != AFX_DAO_DATA_NOT_FOUND);
  3267. }
  3268. BOOL bNullable = FALSE;
  3269. while (nIndex <= nIndexEnd && !bNullable)
  3270. {
  3271. if (!IsFieldStatusNullableKnown(nIndex))
  3272. {
  3273. CDaoFieldInfo fieldinfo;
  3274. GetFieldInfo(nIndex, fieldinfo, AFX_DAO_SECONDARY_INFO);
  3275. bNullable = !fieldinfo.m_bRequired;
  3276. if (bNullable)
  3277. SetNullableFieldStatus(nIndex);
  3278. SetNullableKnownFieldStatus(nIndex);
  3279. }
  3280. else
  3281. bNullable = IsFieldStatusNullable(nIndex);
  3282. nIndex++;
  3283. }
  3284. return bNullable;
  3285. }
  3286. short CDaoRecordset::GetFieldCount()
  3287. {
  3288. ASSERT_VALID(this);
  3289. short nFields;
  3290. if (m_pDAOFields == NULL)
  3291. InitFieldsCollection();
  3292. DAO_CHECK(m_pDAOFields->get_Count(&nFields));
  3293. return nFields;
  3294. }
  3295. void CDaoRecordset::GetFieldInfo(int nIndex, CDaoFieldInfo& fieldinfo,
  3296. DWORD dwInfoOptions)
  3297. {
  3298. ASSERT_VALID(this);
  3299. if (m_pDAOFields == NULL)
  3300. InitFieldsCollection();
  3301. // Get DAOField object and fill in field info struct
  3302. DAOField* pDAOField;
  3303. DAO_CHECK(m_pDAOFields->get_Item(
  3304. COleVariant((long)nIndex), &pDAOField));
  3305. AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
  3306. // Clean up
  3307. pDAOField->Release();
  3308. }
  3309. void CDaoRecordset::GetFieldInfo(LPCTSTR lpszName,
  3310. CDaoFieldInfo& fieldinfo, DWORD dwInfoOptions)
  3311. {
  3312. ASSERT_VALID(this);
  3313. if (m_pDAOFields == NULL)
  3314. InitFieldsCollection();
  3315. // Get DAOField object and fill in field info struct
  3316. DAOField* pDAOField;
  3317. DAO_CHECK(m_pDAOFields->get_Item(
  3318. COleVariant(lpszName, VT_BSTRT), &pDAOField));
  3319. AfxGetFieldInfo(pDAOField, fieldinfo, dwInfoOptions);
  3320. // Clean up
  3321. pDAOField->Release();
  3322. }
  3323. short CDaoRecordset::GetIndexCount()
  3324. {
  3325. ASSERT_VALID(this);
  3326. short nIndexes;
  3327. if (m_pDAOIndexes == NULL)
  3328. InitIndexesCollection();
  3329. DAO_CHECK(m_pDAOIndexes->get_Count(&nIndexes));
  3330. return nIndexes;
  3331. }
  3332. void CDaoRecordset::GetIndexInfo(int nIndex, CDaoIndexInfo& indexinfo,
  3333. DWORD dwInfoOptions)
  3334. {
  3335. ASSERT_VALID(this);
  3336. if (m_pDAOIndexes == NULL)
  3337. InitIndexesCollection();
  3338. // Get DAOField object and fill in field info struct
  3339. DAOIndex* pDAOIndex;
  3340. DAO_CHECK(m_pDAOIndexes->get_Item(
  3341. COleVariant((long)nIndex), &pDAOIndex));
  3342. AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
  3343. // Clean up
  3344. pDAOIndex->Release();
  3345. }
  3346. void CDaoRecordset::GetIndexInfo(LPCTSTR lpszName,
  3347. CDaoIndexInfo& indexinfo, DWORD dwInfoOptions)
  3348. {
  3349. ASSERT_VALID(this);
  3350. if (m_pDAOIndexes == NULL)
  3351. InitIndexesCollection();
  3352. // Get DAOField object and fill in field info struct
  3353. DAOIndex* pDAOIndex;
  3354. DAO_CHECK(m_pDAOIndexes->get_Item(
  3355. COleVariant(lpszName, VT_BSTRT), &pDAOIndex));
  3356. AfxGetIndexInfo(pDAOIndex, indexinfo, dwInfoOptions);
  3357. // Clean up
  3358. pDAOIndex->Release();
  3359. }
  3360. COleVariant CDaoRecordset::GetBookmark()
  3361. {
  3362. ASSERT_VALID(this);
  3363. ASSERT(IsOpen());
  3364. ASSERT(m_pDAORecordset != NULL);
  3365. COleVariant var;
  3366. DAO_CHECK(m_pDAORecordset->get_Bookmark(&var.parray));
  3367. var.vt = VT_ARRAY | VT_UI1;
  3368. return var;
  3369. }
  3370. void CDaoRecordset::SetBookmark(COleVariant varBookmark)
  3371. {
  3372. ASSERT_VALID(this);
  3373. ASSERT(IsOpen());
  3374. ASSERT(m_pDAORecordset != NULL);
  3375. DAO_CHECK(m_pDAORecordset->put_Bookmark(&varBookmark.parray));
  3376. GetDataAndFixupNulls();
  3377. }
  3378. long CDaoRecordset::GetAbsolutePosition()
  3379. {
  3380. ASSERT_VALID(this);
  3381. ASSERT(IsOpen());
  3382. ASSERT(m_pDAORecordset != NULL);
  3383. long lPosition;
  3384. DAO_CHECK(m_pDAORecordset->get_AbsolutePosition(&lPosition));
  3385. return lPosition;
  3386. }
  3387. void CDaoRecordset::SetAbsolutePosition(long lPosition)
  3388. {
  3389. ASSERT_VALID(this);
  3390. ASSERT(IsOpen());
  3391. ASSERT(m_pDAORecordset != NULL);
  3392. DAO_CHECK(m_pDAORecordset->put_AbsolutePosition(lPosition));
  3393. GetDataAndFixupNulls();
  3394. }
  3395. float CDaoRecordset::GetPercentPosition()
  3396. {
  3397. ASSERT_VALID(this);
  3398. ASSERT(IsOpen());
  3399. ASSERT(m_pDAORecordset != NULL);
  3400. float fPosition;
  3401. DAO_CHECK(m_pDAORecordset->get_PercentPosition(&fPosition));
  3402. return fPosition;
  3403. }
  3404. void CDaoRecordset::SetPercentPosition(float fPosition)
  3405. {
  3406. ASSERT_VALID(this);
  3407. ASSERT(IsOpen());
  3408. ASSERT(m_pDAORecordset != NULL);
  3409. DAO_CHECK(m_pDAORecordset->put_PercentPosition(fPosition));
  3410. GetDataAndFixupNulls();
  3411. }
  3412. void CDaoRecordset::MoveNext()
  3413. {
  3414. ASSERT_VALID(this);
  3415. Move(AFX_DAO_NEXT);
  3416. }
  3417. void CDaoRecordset::MovePrev()
  3418. {
  3419. ASSERT_VALID(this);
  3420. Move(AFX_DAO_PREV);
  3421. }
  3422. void CDaoRecordset::MoveFirst()
  3423. {
  3424. ASSERT_VALID(this);
  3425. Move(AFX_DAO_FIRST);
  3426. }
  3427. void CDaoRecordset::MoveLast()
  3428. {
  3429. ASSERT_VALID(this);
  3430. Move(AFX_DAO_LAST);
  3431. }
  3432. void CDaoRecordset::Move(long lRows)
  3433. {
  3434. ASSERT_VALID(this);
  3435. ASSERT(IsOpen());
  3436. ASSERT(m_pDAORecordset != NULL);
  3437. switch(lRows)
  3438. {
  3439. case AFX_DAO_NEXT:
  3440. DAO_CHECK(m_pDAORecordset->MoveNext());
  3441. break;
  3442. case AFX_DAO_PREV:
  3443. DAO_CHECK(m_pDAORecordset->MovePrevious());
  3444. break;
  3445. case AFX_DAO_FIRST:
  3446. DAO_CHECK(m_pDAORecordset->MoveFirst());
  3447. break;
  3448. case AFX_DAO_LAST:
  3449. DAO_CHECK(m_pDAORecordset->_30_MoveLast());
  3450. break;
  3451. // General case
  3452. default:
  3453. // Call Move without getting Bookmark (using unitialized variant).
  3454. DAO_CHECK(m_pDAORecordset->Move(lRows, COleVariant()));
  3455. }
  3456. GetDataAndFixupNulls();
  3457. }
  3458. BOOL CDaoRecordset::FindNext(LPCTSTR lpszFilter)
  3459. {
  3460. ASSERT_VALID(this);
  3461. return Find(AFX_DAO_NEXT, lpszFilter);
  3462. }
  3463. BOOL CDaoRecordset::FindPrev(LPCTSTR lpszFilter)
  3464. {
  3465. ASSERT_VALID(this);
  3466. return Find(AFX_DAO_PREV, lpszFilter);
  3467. }
  3468. BOOL CDaoRecordset::FindFirst(LPCTSTR lpszFilter)
  3469. {
  3470. ASSERT_VALID(this);
  3471. return Find(AFX_DAO_FIRST, lpszFilter);
  3472. }
  3473. BOOL CDaoRecordset::FindLast(LPCTSTR lpszFilter)
  3474. {
  3475. ASSERT_VALID(this);
  3476. return Find(AFX_DAO_LAST, lpszFilter);
  3477. }
  3478. BOOL CDaoRecordset::Find(long lType, LPCTSTR lpszFilter)
  3479. {
  3480. ASSERT_VALID(this);
  3481. ASSERT(IsOpen());
  3482. ASSERT(m_pDAORecordset != NULL);
  3483. COleVariant var(lpszFilter, VT_BSTRT);
  3484. switch(lType)
  3485. {
  3486. default:
  3487. // Invalid Find type!
  3488. ASSERT(FALSE);
  3489. // fall through to FindNext case
  3490. case AFX_DAO_NEXT:
  3491. DAO_CHECK(m_pDAORecordset->FindNext(V_BSTR(&var)));
  3492. break;
  3493. case AFX_DAO_PREV:
  3494. DAO_CHECK(m_pDAORecordset->FindPrevious(V_BSTR(&var)));
  3495. break;
  3496. case AFX_DAO_FIRST:
  3497. DAO_CHECK(m_pDAORecordset->FindFirst(V_BSTR(&var)));
  3498. break;
  3499. case AFX_DAO_LAST:
  3500. DAO_CHECK(m_pDAORecordset->FindLast(V_BSTR(&var)));
  3501. break;
  3502. }
  3503. BOOL bMatch = IsMatch();
  3504. if (bMatch)
  3505. GetDataAndFixupNulls();
  3506. return bMatch;
  3507. }
  3508. BOOL CDaoRecordset::Seek(LPCTSTR lpszComparison, COleVariant* pKey1,
  3509. COleVariant* pKey2, COleVariant* pKey3)
  3510. {
  3511. ASSERT_VALID(this);
  3512. ASSERT(IsOpen());
  3513. ASSERT(m_pDAORecordset != NULL);
  3514. ASSERT(m_nOpenType == dbOpenTable);
  3515. // Must have at least one key
  3516. ASSERT(pKey1 != NULL);
  3517. COleVariant varComparison(lpszComparison, VT_BSTRT);
  3518. DAO_CHECK(m_pDAORecordset->Seek(V_BSTR(&varComparison),
  3519. pKey1 != NULL ? (VARIANT)*pKey1 : _afxOptionalVariant,
  3520. pKey2 != NULL ? (VARIANT)*pKey2 : _afxOptionalVariant,
  3521. pKey3 != NULL ? (VARIANT)*pKey3 : _afxOptionalVariant,
  3522. _afxOptionalVariant, _afxOptionalVariant, _afxOptionalVariant,
  3523. _afxOptionalVariant, _afxOptionalVariant, _afxOptionalVariant,
  3524. _afxOptionalVariant, _afxOptionalVariant, _afxOptionalVariant,
  3525. _afxOptionalVariant));
  3526. BOOL bMatch = IsMatch();
  3527. if (bMatch)
  3528. GetDataAndFixupNulls();
  3529. return bMatch;
  3530. }
  3531. BOOL CDaoRecordset::Seek(LPCTSTR lpszComparison, COleVariant* pKeyArray,
  3532. WORD nKeys)
  3533. {
  3534. ASSERT_VALID(this);
  3535. ASSERT(IsOpen());
  3536. ASSERT(m_pDAORecordset != NULL);
  3537. ASSERT(m_nOpenType == dbOpenTable);
  3538. // Must have at least one key and no more than 13
  3539. ASSERT(nKeys > 0);
  3540. ASSERT(nKeys < 14);
  3541. COleVariant varComparison(lpszComparison, VT_BSTRT);
  3542. LPVARIANT pVarArray[13];
  3543. for (WORD nIndex = 0; nIndex < nKeys; nIndex++)
  3544. pVarArray[nIndex] = &pKeyArray[nIndex];
  3545. for (;nIndex < 13; nIndex++)
  3546. pVarArray[nIndex] = &_afxOptionalVariant;
  3547. DAO_CHECK(m_pDAORecordset->Seek(V_BSTR(&varComparison),
  3548. *pVarArray[0], *pVarArray[1], *pVarArray[2], *pVarArray[3],
  3549. *pVarArray[4], *pVarArray[5], *pVarArray[6], *pVarArray[7],
  3550. *pVarArray[8], *pVarArray[9], *pVarArray[10], *pVarArray[11],
  3551. *pVarArray[12]));
  3552. BOOL bMatch = IsMatch();
  3553. if (bMatch)
  3554. GetDataAndFixupNulls();
  3555. return bMatch;
  3556. }
  3557. void CDaoRecordset::CancelUpdate()
  3558. {
  3559. ASSERT_VALID(this);
  3560. ASSERT(IsOpen());
  3561. ASSERT(m_pDAORecordset != NULL);
  3562. DAO_CHECK(m_pDAORecordset->_30_CancelUpdate());
  3563. // Restore cache if necessary
  3564. if (m_bCheckCacheForDirtyFields && m_nFields > 0)
  3565. LoadFields();
  3566. }
  3567. void CDaoRecordset::SetLockingMode(BOOL bPessimistic)
  3568. {
  3569. ASSERT_VALID(this);
  3570. ASSERT(IsOpen());
  3571. ASSERT(m_pDAORecordset != NULL);
  3572. DAO_CHECK(m_pDAORecordset->put_LockEdits(
  3573. (short)(bPessimistic ? AFX_DAO_TRUE : AFX_DAO_FALSE)));
  3574. }
  3575. BOOL CDaoRecordset::GetLockingMode()
  3576. {
  3577. ASSERT_VALID(this);
  3578. ASSERT(IsOpen());
  3579. ASSERT(m_pDAORecordset != NULL);
  3580. short nLockEdits;
  3581. DAO_CHECK(m_pDAORecordset->get_LockEdits(&nLockEdits));
  3582. return nLockEdits == AFX_DAO_TRUE;
  3583. }
  3584. void CDaoRecordset::SetCacheStart(COleVariant varBookmark)
  3585. {
  3586. ASSERT_VALID(this);
  3587. ASSERT(IsOpen());
  3588. ASSERT(m_pDAORecordset != NULL);
  3589. DAO_CHECK(m_pDAORecordset->put_CacheStart(&varBookmark.parray));
  3590. }
  3591. COleVariant CDaoRecordset::GetCacheStart()
  3592. {
  3593. ASSERT_VALID(this);
  3594. ASSERT(IsOpen());
  3595. ASSERT(m_pDAORecordset != NULL);
  3596. COleVariant var;
  3597. DAO_CHECK(m_pDAORecordset->get_CacheStart(&var.parray));
  3598. var.vt = VT_ARRAY | VT_UI1;
  3599. return var;
  3600. }
  3601. void CDaoRecordset::SetCacheSize(long lSize)
  3602. {
  3603. ASSERT_VALID(this);
  3604. ASSERT(IsOpen());
  3605. ASSERT(m_pDAORecordset != NULL);
  3606. DAO_CHECK(m_pDAORecordset->put_CacheSize(lSize));
  3607. }
  3608. long CDaoRecordset::GetCacheSize()
  3609. {
  3610. ASSERT_VALID(this);
  3611. ASSERT(IsOpen());
  3612. ASSERT(m_pDAORecordset != NULL);
  3613. long lSize;
  3614. DAO_CHECK(m_pDAORecordset->get_CacheSize(&lSize));
  3615. return lSize;
  3616. }
  3617. void CDaoRecordset::FillCache(long* pSize, COleVariant* pBookmark)
  3618. {
  3619. ASSERT_VALID(this);
  3620. ASSERT(IsOpen());
  3621. ASSERT(m_pDAORecordset != NULL);
  3622. DAO_CHECK(m_pDAORecordset->FillCache(
  3623. pSize != NULL ? (VARIANT)COleVariant(*pSize) : _afxOptionalVariant,
  3624. pBookmark != NULL ? (VARIANT)*pBookmark : _afxOptionalVariant));
  3625. }
  3626. void CDaoRecordset::AddNew()
  3627. {
  3628. ASSERT_VALID(this);
  3629. ASSERT(IsOpen());
  3630. ASSERT(m_pDAORecordset != NULL);
  3631. if (m_bCheckCacheForDirtyFields && m_nFields > 0)
  3632. {
  3633. short nEditMode = GetEditMode();
  3634. if (nEditMode != dbEditAdd)
  3635. {
  3636. // Store fields if necessary (fields already stored if edit mode)
  3637. if (nEditMode != dbEditInProgress)
  3638. {
  3639. AllocCache();
  3640. StoreFields();
  3641. }
  3642. // Set all fields NULL and not dirty
  3643. SetFieldNull(NULL);
  3644. SetFieldDirty(NULL, FALSE);
  3645. }
  3646. }
  3647. DAO_CHECK(m_pDAORecordset->AddNew());
  3648. }
  3649. void CDaoRecordset::Edit()
  3650. {
  3651. ASSERT_VALID(this);
  3652. ASSERT(IsOpen());
  3653. ASSERT(m_pDAORecordset != NULL);
  3654. if (m_bCheckCacheForDirtyFields && m_nFields > 0)
  3655. {
  3656. short nEditMode = GetEditMode();
  3657. if (nEditMode != dbEditInProgress)
  3658. {
  3659. if (nEditMode == dbEditNone)
  3660. {
  3661. // Save fields for restore/dirty checking later
  3662. AllocCache();
  3663. StoreFields();
  3664. SetFieldDirty(NULL, FALSE);
  3665. }
  3666. else
  3667. // Load in fields cached on AddNew call prior to Edit
  3668. LoadFields();
  3669. }
  3670. }
  3671. DAO_CHECK(m_pDAORecordset->Edit());
  3672. }
  3673. void CDaoRecordset::Update()
  3674. {
  3675. ASSERT_VALID(this);
  3676. ASSERT(IsOpen());
  3677. ASSERT(m_pDAORecordset != NULL);
  3678. int nMode = 0;
  3679. // If caching, compare cache to current values and save state
  3680. if (m_nFields > 0)
  3681. {
  3682. if (m_bCheckCacheForDirtyFields)
  3683. {
  3684. IsFieldDirty(NULL);
  3685. nMode = GetEditMode();
  3686. }
  3687. // Set all field values of all fields marked dirty
  3688. SetDirtyFields();
  3689. }
  3690. DAO_CHECK(m_pDAORecordset->_30_Update());
  3691. // Restore data if data cached and were in add mode
  3692. if (m_bCheckCacheForDirtyFields && m_nFields > 0 &&
  3693. nMode == dbEditAdd)
  3694. {
  3695. LoadFields();
  3696. }
  3697. }
  3698. void CDaoRecordset::Delete()
  3699. {
  3700. ASSERT_VALID(this);
  3701. ASSERT(IsOpen());
  3702. ASSERT(m_pDAORecordset != NULL);
  3703. DAO_CHECK(m_pDAORecordset->Delete());
  3704. if (m_bCheckCacheForDirtyFields && m_nFields > 0)
  3705. {
  3706. SetFieldNull(NULL);
  3707. SetFieldDirty(NULL, FALSE);
  3708. }
  3709. m_bDeleted = TRUE;
  3710. }
  3711. COleVariant CDaoRecordset::GetFieldValue(LPCTSTR lpszName)
  3712. {
  3713. COleVariant var;
  3714. GetFieldValue(lpszName, var);
  3715. return var;
  3716. }
  3717. COleVariant CDaoRecordset::GetFieldValue(int nIndex)
  3718. {
  3719. COleVariant var;
  3720. GetFieldValue(nIndex, var);
  3721. return var;
  3722. }
  3723. void CDaoRecordset::GetFieldValue(LPCTSTR lpszName, COleVariant& varValue)
  3724. {
  3725. ASSERT_VALID(this);
  3726. ASSERT(IsOpen());
  3727. ASSERT(m_pDAORecordset != NULL);
  3728. // Clear out variant
  3729. varValue.Clear();
  3730. // Use DAO optimization. get_Collect will get the field object from
  3731. // the fields collection and fetch the value
  3732. DAO_CHECK(m_pDAORecordset->get_Collect(
  3733. COleVariant(lpszName, VT_BSTRT), &varValue));
  3734. }
  3735. void CDaoRecordset::GetFieldValue(int nIndex, COleVariant& varValue)
  3736. {
  3737. ASSERT_VALID(this);
  3738. ASSERT(IsOpen());
  3739. ASSERT(m_pDAORecordset != NULL);
  3740. // Clear out variant
  3741. varValue.Clear();
  3742. // Use DAO optimization. get_Collect will get the field object from
  3743. // the fields collection and fetch the value
  3744. DAO_CHECK(m_pDAORecordset->get_Collect(
  3745. COleVariant((long)nIndex), &varValue));
  3746. }
  3747. void CDaoRecordset::SetFieldValue(LPCTSTR lpszName,
  3748. const COleVariant& varValue)
  3749. {
  3750. ASSERT_VALID(this);
  3751. ASSERT(IsOpen());
  3752. ASSERT(m_pDAORecordset != NULL);
  3753. // Use DAO optimization. get_Collect will get the field object from
  3754. // the fields collection and fetch the value
  3755. DAO_CHECK(m_pDAORecordset->put_Collect(
  3756. COleVariant(lpszName, VT_BSTRT), varValue));
  3757. }
  3758. void CDaoRecordset::SetFieldValue(int nIndex,
  3759. const COleVariant& varValue)
  3760. {
  3761. ASSERT_VALID(this);
  3762. ASSERT(IsOpen());
  3763. ASSERT(m_pDAORecordset != NULL);
  3764. // Use DAO optimization. put_Collect will get the field object from
  3765. // the fields collection and write the value
  3766. DAO_CHECK(m_pDAORecordset->put_Collect(
  3767. COleVariant((long)nIndex), varValue));
  3768. }
  3769. void CDaoRecordset::SetFieldValue(int nIndex,
  3770. LPCTSTR lpszValue)
  3771. {
  3772. COleVariant varValue(lpszValue, VT_BSTRT);
  3773. SetFieldValue(nIndex, varValue);
  3774. }
  3775. void CDaoRecordset::SetFieldValue(LPCTSTR lpszName,
  3776. LPCTSTR lpszValue)
  3777. {
  3778. COleVariant varValue(lpszValue, VT_BSTRT);
  3779. SetFieldValue(lpszName, varValue);
  3780. }
  3781. void CDaoRecordset::SetFieldValueNull(LPCTSTR lpszName)
  3782. {
  3783. ASSERT_VALID(this);
  3784. SetFieldValue(lpszName, _afxNullVariant);
  3785. }
  3786. void CDaoRecordset::SetFieldValueNull(int nIndex)
  3787. {
  3788. ASSERT_VALID(this);
  3789. SetFieldValue(nIndex, _afxNullVariant);
  3790. }
  3791. COleVariant CDaoRecordset::GetParamValue(LPCTSTR lpszName)
  3792. {
  3793. ASSERT_VALID(this);
  3794. ASSERT(IsOpen());
  3795. ASSERT(m_pQueryDef != NULL);
  3796. return m_pQueryDef->GetParamValue(lpszName);
  3797. }
  3798. COleVariant CDaoRecordset::GetParamValue(int nIndex)
  3799. {
  3800. ASSERT_VALID(this);
  3801. ASSERT(IsOpen());
  3802. ASSERT(m_pQueryDef != NULL);
  3803. return m_pQueryDef->GetParamValue(nIndex);
  3804. }
  3805. void CDaoRecordset::SetParamValue(LPCTSTR lpszName,
  3806. const COleVariant& varValue)
  3807. {
  3808. ASSERT_VALID(this);
  3809. ASSERT(IsOpen());
  3810. ASSERT(m_pQueryDef != NULL);
  3811. m_pQueryDef->SetParamValue(lpszName, varValue);
  3812. }
  3813. void CDaoRecordset::SetParamValue(int nIndex,
  3814. const COleVariant& varValue)
  3815. {
  3816. ASSERT_VALID(this);
  3817. ASSERT(IsOpen());
  3818. ASSERT(m_pQueryDef != NULL);
  3819. m_pQueryDef->SetParamValue(nIndex, varValue);
  3820. }
  3821. void CDaoRecordset::SetParamValueNull(LPCTSTR lpszName)
  3822. {
  3823. ASSERT_VALID(this);
  3824. SetParamValue(lpszName, _afxNullVariant);
  3825. }
  3826. void CDaoRecordset::SetParamValueNull(int nIndex)
  3827. {
  3828. ASSERT_VALID(this);
  3829. SetParamValue(nIndex, _afxNullVariant);
  3830. }
  3831. //Implementation functions
  3832. DWORD CDaoRecordset::GetFieldLength(int nFieldIndex)
  3833. {
  3834. ASSERT_VALID(this);
  3835. ASSERT(IsOpen());
  3836. return m_pulColumnLengths[nFieldIndex];
  3837. }
  3838. void CDaoRecordset::InitFieldsCollection()
  3839. {
  3840. ASSERT_VALID(this);
  3841. ASSERT(IsOpen());
  3842. DAO_CHECK(m_pDAORecordset->get_Fields(&m_pDAOFields));
  3843. }
  3844. void CDaoRecordset::InitIndexesCollection()
  3845. {
  3846. ASSERT_VALID(this);
  3847. ASSERT(IsOpen());
  3848. DAO_CHECK(m_pTableDef->m_pDAOTableDef->get_Indexes(&m_pDAOIndexes));
  3849. }
  3850. // "PARAMETERS <parameter list>;"
  3851. // "SELECT <select list> FROM <table list>"
  3852. // " WHERE <m_strFilter> ORDER BY <m_strSort>"
  3853. void CDaoRecordset::BuildSQL()
  3854. {
  3855. ASSERT_VALID(this);
  3856. // Assumes m_strSQL represents table list
  3857. CString strTableName = m_strSQL;
  3858. m_strSQL.Empty();
  3859. if (m_nParams > 0)
  3860. BuildParameterList();
  3861. BuildSelectList();
  3862. m_strSQL += _afxFrom2 + strTableName;
  3863. if (!m_strFilter.IsEmpty())
  3864. {
  3865. m_strSQL += _afxWhere2;
  3866. m_strSQL += m_strFilter;
  3867. }
  3868. if (!m_strSort.IsEmpty())
  3869. {
  3870. m_strSQL += _afxOrderBy2;
  3871. m_strSQL += m_strSort;
  3872. }
  3873. }
  3874. void CDaoRecordset::AllocDatabase()
  3875. {
  3876. ASSERT_VALID(this);
  3877. // Allocate and maintain database if necessary
  3878. if (m_pDatabase == NULL)
  3879. {
  3880. m_pDatabase = new CDaoDatabase;
  3881. m_pDatabase->m_nStatus |= AFX_DAO_IMPLICIT_DB;
  3882. m_nStatus |= AFX_DAO_IMPLICIT_DB;
  3883. }
  3884. // Open Database if necessary
  3885. if (!m_pDatabase->IsOpen())
  3886. m_pDatabase->Open((LPCTSTR)GetDefaultDBName(), FALSE, FALSE, NULL);
  3887. }
  3888. void CDaoRecordset::BuildSelectList()
  3889. {
  3890. ASSERT_VALID(this);
  3891. ASSERT(m_nFields > 0);
  3892. m_strSQL += _afxSelect2;
  3893. CDaoFieldExchange fx(CDaoFieldExchange::AddToSelectList, this);
  3894. DoFieldExchange(&fx);
  3895. }
  3896. void CDaoRecordset::BuildParameterList()
  3897. {
  3898. ASSERT_VALID(this);
  3899. ASSERT(m_nParams > 0);
  3900. m_strSQL += _afxParameters2;
  3901. CDaoFieldExchange fx(CDaoFieldExchange::AddToParameterList, this);
  3902. DoFieldExchange(&fx);
  3903. if (fx.m_nParam != 0)
  3904. m_strSQL += _T(";");
  3905. else
  3906. m_strSQL.Empty();
  3907. }
  3908. void CDaoRecordset::BindFields()
  3909. {
  3910. ASSERT_VALID(this);
  3911. if (m_nFields > 0)
  3912. {
  3913. // Setup the DAO binding struct
  3914. ASSERT(m_prgDaoColBindInfo == NULL);
  3915. m_prgDaoColBindInfo = new DAOCOLUMNBINDING[m_nFields];
  3916. memset(m_prgDaoColBindInfo, 0, sizeof(DAOCOLUMNBINDING) * m_nFields);
  3917. m_pulColumnLengths = new DWORD[m_nFields];
  3918. memset(m_pulColumnLengths, 0, sizeof(DWORD) * m_nFields);
  3919. m_pbFieldFlags = new BYTE[m_nFields];
  3920. memset(m_pbFieldFlags, 0, m_nFields);
  3921. m_DaoFetchRows.cRowsRequested = 1;
  3922. m_DaoFetchRows.dwFlags = DAOROWFETCH_BINDABSOLUTE;
  3923. m_DaoFetchRows.pData = NULL;
  3924. // Allocate the index map
  3925. ASSERT(m_pMapFieldIndex == NULL);
  3926. m_pMapFieldIndex = new CMapPtrToPtr;
  3927. CDaoFieldExchange fx(CDaoFieldExchange::BindField, this);
  3928. DoFieldExchange(&fx);
  3929. }
  3930. }
  3931. void CDaoRecordset::BindParameters()
  3932. {
  3933. ASSERT_VALID(this);
  3934. if (m_nParams > 0)
  3935. {
  3936. // Since Jet treats non-bindable names as implicit parameters
  3937. // this should catch some SQL syntax errors that would otherwise
  3938. // appear to be uninitialized parameters.
  3939. ASSERT(m_pQueryDef->GetParameterCount() == m_nParams);
  3940. CDaoFieldExchange fx(CDaoFieldExchange::BindParam, this);
  3941. DoFieldExchange(&fx);
  3942. }
  3943. }
  3944. void CDaoRecordset::Fixup()
  3945. {
  3946. ASSERT_VALID(this);
  3947. CDaoFieldExchange fx(CDaoFieldExchange::Fixup, this);
  3948. DoFieldExchange(&fx);
  3949. }
  3950. void CDaoRecordset::AllocCache()
  3951. {
  3952. ASSERT_VALID(this);
  3953. // Do nothing if caching disabled by master switch
  3954. if (m_bCheckCacheForDirtyFields && m_nFields > 0 &&
  3955. m_pMapFieldCache == NULL)
  3956. {
  3957. m_pMapFieldCache = new CMapPtrToPtr;
  3958. CDaoFieldExchange fx(CDaoFieldExchange::AllocCache, this);
  3959. DoFieldExchange(&fx);
  3960. }
  3961. }
  3962. void CDaoRecordset::StoreFields()
  3963. {
  3964. ASSERT_VALID(this);
  3965. // Do nothing if caching disabled by master switch
  3966. if (m_bCheckCacheForDirtyFields && m_nFields > 0)
  3967. {
  3968. ASSERT(m_pMapFieldCache != NULL);
  3969. CDaoFieldExchange fx(CDaoFieldExchange::StoreField, this);
  3970. DoFieldExchange(&fx);
  3971. }
  3972. }
  3973. void CDaoRecordset::LoadFields()
  3974. {
  3975. ASSERT_VALID(this);
  3976. // Do nothing if caching disabled by master switch
  3977. if (m_bCheckCacheForDirtyFields && m_nFields > 0)
  3978. {
  3979. CDaoFieldExchange fx(CDaoFieldExchange::LoadField, this);
  3980. DoFieldExchange(&fx);
  3981. // Clear the dirty status flags
  3982. SetFieldDirty(NULL, FALSE);
  3983. }
  3984. }
  3985. void CDaoRecordset::FreeCache()
  3986. {
  3987. ASSERT_VALID(this);
  3988. // Do nothing if caching disabled by master switch
  3989. if (m_bCheckCacheForDirtyFields && m_nFields > 0 &&
  3990. m_pMapFieldCache != NULL)
  3991. {
  3992. // Free up dynamically allocated mem in cache
  3993. CDaoFieldExchange fx(CDaoFieldExchange::FreeCache, this);
  3994. // Delete any cached data
  3995. void* pvKey;
  3996. void* pvObject;
  3997. POSITION pos = m_pMapFieldCache->GetStartPosition();
  3998. while (pos != NULL)
  3999. {
  4000. m_pMapFieldCache->GetNextAssoc(pos, pvKey, pvObject);
  4001. fx.DeleteCacheValue((CDaoFieldCache*)pvObject,
  4002. ((CDaoFieldCache*)pvObject)->m_nDataType);
  4003. }
  4004. m_pMapFieldCache->RemoveAll();
  4005. delete m_pMapFieldCache;
  4006. m_pMapFieldCache = NULL;
  4007. }
  4008. }
  4009. void CDaoRecordset::MarkForAddNew()
  4010. {
  4011. ASSERT_VALID(this);
  4012. CDaoFieldExchange fx(CDaoFieldExchange::MarkForAddNew, this);
  4013. DoFieldExchange(&fx);
  4014. }
  4015. void CDaoRecordset::MarkForEdit()
  4016. {
  4017. ASSERT_VALID(this);
  4018. CDaoFieldExchange fx(CDaoFieldExchange::MarkForEdit, this);
  4019. DoFieldExchange(&fx);
  4020. }
  4021. int CDaoRecordset::GetFieldIndex(void* pv)
  4022. {
  4023. ASSERT_VALID(this);
  4024. ASSERT(m_pMapFieldIndex != NULL);
  4025. void* pvIndex;
  4026. if (!m_pMapFieldIndex->Lookup(pv, pvIndex))
  4027. return AFX_DAO_DATA_NOT_FOUND;
  4028. else
  4029. // Index was stored rather than ptr, make it 0-based
  4030. return ((int)pvIndex) - 1;
  4031. }
  4032. void CDaoRecordset::SetDirtyFields()
  4033. {
  4034. ASSERT_VALID(this);
  4035. if (m_pDAOFields == NULL)
  4036. InitFieldsCollection();
  4037. CDaoFieldExchange fx(CDaoFieldExchange::SetDirtyField, this);
  4038. DoFieldExchange(&fx);
  4039. }
  4040. void CDaoRecordset::SetCursorAttributes()
  4041. {
  4042. ASSERT_VALID(this);
  4043. m_bScrollable = !(m_nOptions & dbForwardOnly);
  4044. m_bAppendable = CanUpdate() ||
  4045. (!(m_nOptions & dbReadOnly) && (m_nOptions & dbAppendOnly));
  4046. }
  4047. void CDaoRecordset::GetDataAndFixupNulls()
  4048. {
  4049. ASSERT_VALID(this);
  4050. // Don't need to do anything if no fields bound
  4051. if (m_nFields > 0)
  4052. {
  4053. if (IsEOF() || IsBOF())
  4054. {
  4055. // If no current record, simple mark fields NULL
  4056. if (m_nFields > 0)
  4057. SetFieldNull(NULL);
  4058. }
  4059. else
  4060. {
  4061. if (m_pICDAORecordsetGetRows == NULL)
  4062. {
  4063. DAO_CHECK(m_pDAORecordset->QueryInterface(
  4064. IID_ICDAORecordset, (void**)&m_pICDAORecordsetGetRows));
  4065. }
  4066. // Call GetRows to fill in the bound data
  4067. SCODE scode = m_pICDAORecordsetGetRows->GetRows(
  4068. 0, m_nFields, m_prgDaoColBindInfo,
  4069. m_cbFixedLengthFields, &m_DaoFetchRows);
  4070. // Check for GetRows specific errors
  4071. // This is necessary as ICDAORecordset::GetRows
  4072. // errors are not appended to DAO errors collection
  4073. if (FAILED(scode))
  4074. ThrowGetRowsDaoException(scode);
  4075. // Check to see if row deleted as it is just warning
  4076. m_bDeleted = scode == S_RECORDDELETED;
  4077. // Reset the status array
  4078. ClearFieldStatusFlags();
  4079. // Fixup Null fields
  4080. Fixup();
  4081. }
  4082. }
  4083. }
  4084. BOOL CDaoRecordset::IsFieldStatusDirty(UINT nField)
  4085. {
  4086. ASSERT_VALID(this);
  4087. return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_DIRTY) ==
  4088. AFX_DAO_FIELD_FLAG_DIRTY);
  4089. }
  4090. void CDaoRecordset::SetDirtyFieldStatus(UINT nField)
  4091. {
  4092. ASSERT_VALID(this);
  4093. m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_DIRTY;
  4094. }
  4095. void CDaoRecordset::ClearDirtyFieldStatus(UINT nField)
  4096. {
  4097. ASSERT_VALID(this);
  4098. m_pbFieldFlags[nField] &= ~AFX_DAO_FIELD_FLAG_DIRTY;
  4099. }
  4100. BOOL CDaoRecordset::IsFieldStatusNull(UINT nField)
  4101. {
  4102. ASSERT_VALID(this);
  4103. return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_NULL) ==
  4104. AFX_DAO_FIELD_FLAG_NULL);
  4105. }
  4106. void CDaoRecordset::SetNullFieldStatus(UINT nField)
  4107. {
  4108. ASSERT_VALID(this);
  4109. m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_NULL;
  4110. }
  4111. void CDaoRecordset::ClearNullFieldStatus(UINT nField)
  4112. {
  4113. ASSERT_VALID(this);
  4114. m_pbFieldFlags[nField] &= ~AFX_DAO_FIELD_FLAG_NULL;
  4115. }
  4116. BOOL CDaoRecordset::IsFieldStatusNullable(UINT nField)
  4117. {
  4118. ASSERT_VALID(this);
  4119. return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_NULLABLE) ==
  4120. AFX_DAO_FIELD_FLAG_NULLABLE);
  4121. }
  4122. void CDaoRecordset::SetNullableFieldStatus(UINT nField)
  4123. {
  4124. ASSERT_VALID(this);
  4125. m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_NULLABLE;
  4126. }
  4127. BOOL CDaoRecordset::IsFieldStatusNullableKnown(UINT nField)
  4128. {
  4129. ASSERT_VALID(this);
  4130. return ((m_pbFieldFlags[nField] & AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN)
  4131. == AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN);
  4132. }
  4133. void CDaoRecordset::SetNullableKnownFieldStatus(UINT nField)
  4134. {
  4135. ASSERT_VALID(this);
  4136. m_pbFieldFlags[nField] |= AFX_DAO_FIELD_FLAG_NULLABLE_KNOWN;
  4137. }
  4138. void CDaoRecordset::ClearFieldStatusFlags()
  4139. {
  4140. ASSERT_VALID(this);
  4141. memset(m_pbFieldFlags, 0, m_nFields);
  4142. }
  4143. BOOL CDaoRecordset::IsMatch()
  4144. {
  4145. ASSERT_VALID(this);
  4146. ASSERT(IsOpen());
  4147. short nNoMatch;
  4148. DAO_CHECK(m_pDAORecordset->get_NoMatch(&nNoMatch));
  4149. // Return TRUE if NoMatch is FALSE
  4150. return nNoMatch == AFX_DAO_FALSE;
  4151. }
  4152. void AFX_CDECL CDaoRecordset::StripBrackets(LPCTSTR lpszSrc, LPTSTR lpszDest)
  4153. {
  4154. while (*lpszSrc != '\0')
  4155. {
  4156. // Ignore all brackets
  4157. while (*lpszSrc == '[' || *lpszSrc == ']')
  4158. lpszSrc = _tcsinc(lpszSrc);
  4159. // Quit if at the end of the string
  4160. if (*lpszSrc == '\0')
  4161. break;
  4162. // Copy the data and increment the buffers
  4163. if (_istlead(*lpszSrc))
  4164. *lpszDest++ = *lpszSrc++;
  4165. *lpszDest++ = *lpszSrc++;
  4166. }
  4167. // Add the trailing '\0'
  4168. *lpszDest = '\0';
  4169. }
  4170. void CDaoRecordset::ThrowDaoException(int nAfxDaoError)
  4171. {
  4172. ASSERT_VALID(this);
  4173. AfxThrowDaoException(nAfxDaoError);
  4174. }
  4175. #ifdef _DEBUG
  4176. void CDaoRecordset::AssertValid() const
  4177. {
  4178. CObject::AssertValid();
  4179. }
  4180. void CDaoRecordset::Dump(CDumpContext& dc) const
  4181. {
  4182. ASSERT_VALID(this);
  4183. CObject::Dump(dc);
  4184. dc << "\nm_bOpen = " << m_bOpen;
  4185. dc << "\nm_bAppendable = " << m_bAppendable;
  4186. dc << "\nm_bScrollable = " << m_bScrollable;
  4187. dc << "\nm_bDeleted = " << m_bDeleted;
  4188. dc << "\nm_nOpenType = " << m_nOpenType;
  4189. dc << "\nm_nDefaultType = " << m_nDefaultType;
  4190. dc << "\nm_nOptions = " << m_nOptions;
  4191. dc << "\nm_strSQL = " << m_strSQL;
  4192. dc << "\nm_strFilter = " << m_strFilter;
  4193. dc << "\nm_strSort = " << m_strSort;
  4194. dc << "\nm_strRequerySQL = " << m_strRequerySQL;
  4195. dc << "\nm_strRequeryFilter = " << m_strRequeryFilter;
  4196. dc << "\nm_strRequerySort = " << m_strRequerySort;
  4197. dc << "\nm_nFields = " << m_nFields;
  4198. dc << "\nm_nParams = " << m_nParams;
  4199. dc << "\nm_bCheckCacheForDirtyFields = " << m_bCheckCacheForDirtyFields;
  4200. dc << "\nm_nStatus = " << m_nStatus;
  4201. dc << "\n";
  4202. }
  4203. #endif //_DEBUG
  4204. //////////////////////////////////////////////////////////////////////////
  4205. // Helpers - implementation
  4206. void AFX_CDECL AfxGetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo,
  4207. DWORD dwInfoOptions)
  4208. {
  4209. ASSERT(pDAOField != NULL);
  4210. ASSERT(dwInfoOptions != 0);
  4211. COleVariant var;
  4212. short nBool;
  4213. // Always fetch the Primary properties
  4214. if (dwInfoOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  4215. {
  4216. DAO_CHECK(pDAOField->get_Name(&V_BSTR(&var)));
  4217. var.vt = VT_BSTR;
  4218. fieldinfo.m_strName = V_BSTRT(&var);
  4219. var.Clear();
  4220. DAO_CHECK(pDAOField->get_Type(&fieldinfo.m_nType));
  4221. DAO_CHECK(pDAOField->get_Size(&fieldinfo.m_lSize));
  4222. DAO_CHECK(pDAOField->get_Attributes(&fieldinfo.m_lAttributes));
  4223. }
  4224. if (dwInfoOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  4225. {
  4226. DAO_CHECK(pDAOField->get_OrdinalPosition(
  4227. &fieldinfo.m_nOrdinalPosition));
  4228. DAO_CHECK(pDAOField->get_Required(&nBool));
  4229. fieldinfo.m_bRequired = nBool == AFX_DAO_TRUE;
  4230. DAO_CHECK(pDAOField->get_AllowZeroLength(&nBool));
  4231. fieldinfo.m_bAllowZeroLength = nBool == AFX_DAO_TRUE;
  4232. DAO_CHECK(pDAOField->get_CollatingOrder(
  4233. &fieldinfo.m_lCollatingOrder));
  4234. DAO_CHECK(pDAOField->get_SourceField(&V_BSTR(&var)));
  4235. var.vt = VT_BSTR;
  4236. fieldinfo.m_strSourceField = V_BSTRT(&var);
  4237. var.Clear();
  4238. DAO_CHECK(pDAOField->get_SourceTable(&V_BSTR(&var)));
  4239. var.vt = VT_BSTR;
  4240. fieldinfo.m_strSourceTable = V_BSTRT(&var);
  4241. var.Clear();
  4242. TRY
  4243. {
  4244. DAO_CHECK(pDAOField->get_ForeignName(&V_BSTR(&var)));
  4245. var.vt = VT_BSTR;
  4246. fieldinfo.m_strForeignName = V_BSTRT(&var);
  4247. var.Clear();
  4248. }
  4249. CATCH(CDaoException, e)
  4250. {
  4251. // If this property not appropriate, set foreign name empty
  4252. if (e->m_scode != E_DAO_IllegalOperation)
  4253. THROW_LAST();
  4254. else
  4255. {
  4256. fieldinfo.m_strForeignName.Empty();
  4257. e->Delete();
  4258. }
  4259. }
  4260. END_CATCH
  4261. }
  4262. if (dwInfoOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
  4263. {
  4264. AfxGetDefaultValue(pDAOField, fieldinfo.m_strDefaultValue);
  4265. DAO_CHECK(pDAOField->get_ValidationRule(&V_BSTR(&var)));
  4266. var.vt = VT_BSTR;
  4267. fieldinfo.m_strValidationRule = V_BSTRT(&var);
  4268. var.Clear();
  4269. DAO_CHECK(pDAOField->get_ValidationText(&V_BSTR(&var)));
  4270. var.vt = VT_BSTR;
  4271. fieldinfo.m_strValidationText = V_BSTRT(&var);
  4272. var.Clear();
  4273. }
  4274. }
  4275. void AFX_CDECL AfxSetFieldInfo(DAOField* pDAOField, CDaoFieldInfo& fieldinfo)
  4276. {
  4277. // Assumes name, type and size set on direct DAO CreateField call
  4278. ASSERT(pDAOField != NULL);
  4279. if (fieldinfo.m_lAttributes != 0)
  4280. DAO_CHECK(pDAOField->put_Attributes(fieldinfo.m_lAttributes));
  4281. if (fieldinfo.m_nOrdinalPosition != 0)
  4282. {
  4283. DAO_CHECK(pDAOField->put_OrdinalPosition(
  4284. fieldinfo.m_nOrdinalPosition));
  4285. }
  4286. if (fieldinfo.m_bRequired)
  4287. DAO_CHECK(pDAOField->put_Required(AFX_DAO_TRUE));
  4288. if (fieldinfo.m_bAllowZeroLength)
  4289. DAO_CHECK(pDAOField->put_AllowZeroLength(AFX_DAO_TRUE));
  4290. if (!fieldinfo.m_strForeignName.IsEmpty())
  4291. {
  4292. COleVariant var(fieldinfo.m_strForeignName, VT_BSTRT);
  4293. DAO_CHECK(pDAOField->put_ForeignName(V_BSTR(&var)));
  4294. }
  4295. if (!fieldinfo.m_strValidationRule.IsEmpty())
  4296. {
  4297. COleVariant var(fieldinfo.m_strValidationRule, VT_BSTRT);
  4298. DAO_CHECK(pDAOField->put_ValidationRule(V_BSTR(&var)));
  4299. }
  4300. if (!fieldinfo.m_strValidationText.IsEmpty())
  4301. {
  4302. COleVariant var(fieldinfo.m_strValidationText, VT_BSTRT);
  4303. DAO_CHECK(pDAOField->put_ValidationText(V_BSTR(&var)));
  4304. }
  4305. if (!fieldinfo.m_strDefaultValue.IsEmpty())
  4306. {
  4307. AfxSetDefaultValue(pDAOField, fieldinfo.m_strDefaultValue);
  4308. }
  4309. }
  4310. void AFX_CDECL AfxGetDefaultValue(DAOField* pDAOField, CString& strDefaultValue)
  4311. {
  4312. COleVariant var;
  4313. BYTE bUseDao = _AfxDetermineDaoVersion();
  4314. if (bUseDao == 35 || bUseDao == 36)
  4315. {
  4316. // Call the DAO 3.5/3.6 method
  4317. DAO_CHECK(pDAOField->get_DefaultValue(&var));
  4318. }
  4319. else
  4320. {
  4321. // Call DAO 3.0 method
  4322. // get_DefaultValue takes BSTR* param not VARIANT*
  4323. HRESULT (STDMETHODCALLTYPE DAOField::*pMethod)(BSTR*) = (HRESULT (STDMETHODCALLTYPE DAOField::*)(BSTR*))pDAOField->get_DefaultValue;
  4324. DAO_CHECK((pDAOField->*pMethod)(&V_BSTR(&var)));
  4325. var.vt = VT_BSTR;
  4326. }
  4327. strDefaultValue = V_BSTRT(&var);
  4328. var.Clear();
  4329. }
  4330. void AFX_CDECL AfxSetDefaultValue(DAOField* pDAOField, CString& strDefaultValue)
  4331. {
  4332. COleVariant var(strDefaultValue, VT_BSTRT);
  4333. BYTE bUseDao = _AfxDetermineDaoVersion();
  4334. if (bUseDao == 35 || bUseDao == 36)
  4335. {
  4336. // Call DAO 3.5/3.6 version
  4337. DAO_CHECK(pDAOField->put_DefaultValue(var));
  4338. }
  4339. else
  4340. {
  4341. // Call DAO 3.0 method
  4342. // put_DefaultValue takes BSTR param not VARIANT
  4343. HRESULT (STDMETHODCALLTYPE DAOField::*pMethod)(BSTR) = (HRESULT (STDMETHODCALLTYPE DAOField::*)(BSTR))pDAOField->put_DefaultValue;
  4344. DAO_CHECK((pDAOField->*pMethod)(V_BSTR(&var)));
  4345. }
  4346. }
  4347. void AFX_CDECL AfxGetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo,
  4348. DWORD dwInfoOptions)
  4349. {
  4350. ASSERT(pDAOIndex != NULL);
  4351. ASSERT(dwInfoOptions != 0);
  4352. COleVariant var;
  4353. short nBool;
  4354. if (dwInfoOptions & AFX_DAO_FETCH_PRIMARY_PROPERTIES)
  4355. {
  4356. DAO_CHECK(pDAOIndex->get_Name(&V_BSTR(&var)));
  4357. var.vt = VT_BSTR;
  4358. indexinfo.m_strName = V_BSTRT(&var);
  4359. var.Clear();
  4360. AfxGetIndexFieldInfo(pDAOIndex, indexinfo);
  4361. }
  4362. if (dwInfoOptions & AFX_DAO_FETCH_SECONDARY_PROPERTIES)
  4363. {
  4364. DAO_CHECK(pDAOIndex->get_Primary(&nBool));
  4365. indexinfo.m_bPrimary = nBool == AFX_DAO_TRUE;
  4366. DAO_CHECK(pDAOIndex->get_Unique(&nBool));
  4367. indexinfo.m_bUnique = nBool == AFX_DAO_TRUE;
  4368. DAO_CHECK(pDAOIndex->get_Clustered(&nBool));
  4369. indexinfo.m_bClustered = nBool == AFX_DAO_TRUE;
  4370. DAO_CHECK(pDAOIndex->get_IgnoreNulls(&nBool));
  4371. indexinfo.m_bIgnoreNulls = nBool == AFX_DAO_TRUE;
  4372. DAO_CHECK(pDAOIndex->get_Required(&nBool));
  4373. indexinfo.m_bRequired = nBool == AFX_DAO_TRUE;
  4374. DAO_CHECK(pDAOIndex->get_Foreign(&nBool));
  4375. indexinfo.m_bForeign = nBool == AFX_DAO_TRUE;
  4376. }
  4377. if (dwInfoOptions & AFX_DAO_FETCH_ALL_PROPERTIES)
  4378. {
  4379. DAO_CHECK(pDAOIndex->get_DistinctCount(
  4380. &indexinfo.m_lDistinctCount));
  4381. }
  4382. }
  4383. void AFX_CDECL AfxSetIndexInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo)
  4384. {
  4385. // Assumes name,set on direct DAO CreateIndex call
  4386. ASSERT(pDAOIndex != NULL);
  4387. AfxSetIndexFieldInfo(pDAOIndex, indexinfo);
  4388. if (indexinfo.m_bPrimary)
  4389. DAO_CHECK(pDAOIndex->put_Primary(AFX_DAO_TRUE));
  4390. if (indexinfo.m_bUnique)
  4391. DAO_CHECK(pDAOIndex->put_Unique(AFX_DAO_TRUE));
  4392. if (indexinfo.m_bClustered)
  4393. DAO_CHECK(pDAOIndex->put_Clustered(AFX_DAO_TRUE));
  4394. if (indexinfo.m_bIgnoreNulls)
  4395. DAO_CHECK(pDAOIndex->put_IgnoreNulls(AFX_DAO_TRUE));
  4396. if (indexinfo.m_bRequired)
  4397. DAO_CHECK(pDAOIndex->put_Required(AFX_DAO_TRUE));
  4398. }
  4399. void AFX_CDECL AfxGetIndexFields(DAOIndex* pDAOIndex,
  4400. DAOIndexFields** ppDAOIndexFields)
  4401. {
  4402. COleVariant var;
  4403. BYTE bUseDao = _AfxDetermineDaoVersion();
  4404. // Set the desired interface
  4405. GUID guidIndexFields;
  4406. if (bUseDao == 35 || bUseDao == 36)
  4407. {
  4408. // Use DAO 3.5/3.6
  4409. #ifdef _UNICODE
  4410. guidIndexFields = IID_IDAOIndexFieldsW;
  4411. #else
  4412. guidIndexFields = IID_IDAOIndexFields;
  4413. #endif
  4414. }
  4415. else
  4416. {
  4417. // Use DAO 3.0
  4418. #ifdef _UNICODE
  4419. guidIndexFields = IID30_IDAOIndexFieldsW;
  4420. #else
  4421. guidIndexFields = IID30_IDAOIndexFields;
  4422. #endif
  4423. }
  4424. // Get dispatch pointer to fields collection
  4425. DAO_CHECK(pDAOIndex->get_Fields(&var));
  4426. DAO_CHECK(var.pdispVal->QueryInterface(
  4427. guidIndexFields, (void**)ppDAOIndexFields));
  4428. }
  4429. void AFX_CDECL AfxGetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo)
  4430. {
  4431. COleVariant var;
  4432. DAOIndexFields* pDAOIndexFields = NULL;
  4433. DAOField* pDAOField = NULL;
  4434. // Get the index fields collection
  4435. AfxGetIndexFields(pDAOIndex, &pDAOIndexFields);
  4436. TRY
  4437. {
  4438. // Get the number of fields in the index
  4439. short nCount;
  4440. DAO_CHECK(pDAOIndexFields->get_Count(&nCount));
  4441. // Allocate or reallocate memory for array if necessary
  4442. if (nCount != indexinfo.m_nFields)
  4443. {
  4444. if (indexinfo.m_nFields != 0)
  4445. {
  4446. // Check that allocation is correct.
  4447. ASSERT(indexinfo.m_nFields == 0 ||
  4448. indexinfo.m_bCleanupFieldInfo);
  4449. delete[] indexinfo.m_pFieldInfos;
  4450. indexinfo.m_pFieldInfos = NULL;
  4451. }
  4452. // Now allocate required memory
  4453. indexinfo.m_pFieldInfos = new CDaoIndexFieldInfo[nCount];
  4454. indexinfo.m_bCleanupFieldInfo = TRUE;
  4455. indexinfo.m_nFields = nCount;
  4456. }
  4457. BYTE bUseDao = _AfxDetermineDaoVersion();
  4458. // Now get field info for each field
  4459. long lAttributes;
  4460. for (short nIndex = 0; nIndex < indexinfo.m_nFields; nIndex++)
  4461. {
  4462. // Set the desired interface
  4463. GUID guidField;
  4464. if (bUseDao == 35 || bUseDao == 36)
  4465. {
  4466. #ifdef _UNICODE
  4467. guidField = IID_IDAOFieldW;
  4468. #else
  4469. guidField = IID_IDAOField;
  4470. #endif
  4471. }
  4472. else
  4473. {
  4474. #ifdef _UNICODE
  4475. guidField = IID30_IDAOFieldW;
  4476. #else
  4477. guidField = IID30_IDAOField;
  4478. #endif
  4479. }
  4480. // Get the field item
  4481. DAO_CHECK(pDAOIndexFields->get_Item(COleVariant(nIndex), &var));
  4482. DAO_CHECK(var.pdispVal->QueryInterface(
  4483. guidField, (void**)&pDAOField));
  4484. var.Clear();
  4485. // Get the field name
  4486. DAO_CHECK(pDAOField->get_Name(&V_BSTR(&var)));
  4487. var.vt = VT_BSTR;
  4488. indexinfo.m_pFieldInfos[nIndex].m_strName = V_BSTRT(&var);
  4489. var.Clear();
  4490. // Get the field attributes
  4491. DAO_CHECK(pDAOField->get_Attributes(&lAttributes));
  4492. indexinfo.m_pFieldInfos[nIndex].m_bDescending =
  4493. (lAttributes & dbDescending);
  4494. // Release and reset the field object
  4495. pDAOField->Release();
  4496. pDAOField = NULL;
  4497. }
  4498. // Release the index fields object
  4499. pDAOIndexFields->Release();
  4500. }
  4501. CATCH_ALL(e)
  4502. {
  4503. // Release the field object if necessary
  4504. if (pDAOField != NULL)
  4505. pDAOField->Release();
  4506. // Must always release index fields collection
  4507. pDAOIndexFields->Release();
  4508. THROW_LAST();
  4509. }
  4510. END_CATCH_ALL
  4511. }
  4512. void AFX_CDECL AfxSetIndexFieldInfo(DAOIndex* pDAOIndex, CDaoIndexInfo& indexinfo)
  4513. {
  4514. COleVariant var;
  4515. long lAttributes;
  4516. DAOIndexFields* pDAOIndexFields = NULL;
  4517. DAOField* pDAOField = NULL;
  4518. // Get the index fields collection
  4519. AfxGetIndexFields(pDAOIndex, &pDAOIndexFields);
  4520. TRY
  4521. {
  4522. for (int nIndex = 0; nIndex < indexinfo.m_nFields; nIndex++)
  4523. {
  4524. // Create the field and set the name
  4525. DAO_CHECK(pDAOIndex->CreateField(
  4526. COleVariant(indexinfo.m_pFieldInfos[nIndex].m_strName, VT_BSTRT),
  4527. _afxOptionalVariant, _afxOptionalVariant, &pDAOField));
  4528. // Set the descending property
  4529. if (indexinfo.m_pFieldInfos[nIndex].m_bDescending)
  4530. lAttributes = dbDescending;
  4531. else
  4532. lAttributes = 0;
  4533. DAO_CHECK(pDAOField->put_Attributes(lAttributes));
  4534. // Append field to collection, release and reset
  4535. pDAOIndexFields->Append(pDAOField);
  4536. pDAOField->Release();
  4537. pDAOField = NULL;
  4538. }
  4539. // Always release the index fields object
  4540. pDAOIndexFields->Release();
  4541. }
  4542. CATCH_ALL(e)
  4543. {
  4544. if (pDAOField != NULL)
  4545. pDAOField->Release();
  4546. pDAOIndexFields->Release();
  4547. THROW_LAST();
  4548. }
  4549. END_CATCH_ALL
  4550. }
  4551. //////////////////////////////////////////////////////////////////////////////
  4552. // GetRows helper
  4553. void AFX_CDECL ThrowGetRowsDaoException(SCODE scode)
  4554. {
  4555. switch (scode)
  4556. {
  4557. case E_OUTOFMEMORY:
  4558. AfxThrowMemoryException();
  4559. default:
  4560. AfxThrowDaoException(NO_AFX_DAO_ERROR, scode);
  4561. // These are only (known) DAO 3.0 GetRows errors
  4562. case E_ROWTOOSHORT:
  4563. case E_BADBINDINFO:
  4564. case E_COLUMNUNAVAILABLE:
  4565. break;
  4566. }
  4567. CDaoException* pException;
  4568. pException = new CDaoException;
  4569. pException->m_pErrorInfo = new CDaoErrorInfo;
  4570. // Fill out the DAO error info struct
  4571. pException->m_scode = scode;
  4572. pException->m_pErrorInfo->m_strSource = _T("ICDAORecordset.GetRows");
  4573. pException->m_pErrorInfo->m_lErrorCode = LOWORD(scode);
  4574. // There is no help context or help file
  4575. pException->m_pErrorInfo->m_lHelpContext = 0;
  4576. int nID = 0;
  4577. if (scode == E_ROWTOOSHORT)
  4578. nID = AFX_IDP_DAO_ROWTOOSHORT;
  4579. else if (scode == E_BADBINDINFO)
  4580. nID = AFX_IDP_DAO_BADBINDINFO;
  4581. else
  4582. nID = AFX_IDP_DAO_COLUMNUNAVAILABLE;
  4583. VERIFY(pException->m_pErrorInfo->m_strDescription.LoadString(nID));
  4584. #ifdef _DEBUG
  4585. if (afxTraceFlags & traceDatabase)
  4586. {
  4587. TRACE1("\nError Code = %d\n",
  4588. pException->m_pErrorInfo->m_lErrorCode);
  4589. TRACE1("Source = %s\n",
  4590. (LPCTSTR)pException->m_pErrorInfo->m_strSource);
  4591. TRACE1("Description = %s\n",
  4592. (LPCTSTR)pException->m_pErrorInfo->m_strDescription);
  4593. }
  4594. #endif
  4595. THROW(pException);
  4596. }
  4597. //////////////////////////////////////////////////////////////////////////////
  4598. // _AFX_DAO_STATE helper
  4599. _AFX_DAO_STATE* AFX_CDECL AfxGetDaoState()
  4600. {
  4601. // The DAO state is store in the module state
  4602. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  4603. _AFX_DAO_STATE* pDaoState = pModuleState->m_pDaoState;
  4604. // Allocate a new DAO state if necessary
  4605. if (pDaoState == NULL)
  4606. {
  4607. pDaoState = new _AFX_DAO_STATE;
  4608. pModuleState->m_pDaoState = pDaoState;
  4609. }
  4610. return pDaoState;
  4611. }
  4612. //////////////////////////////////////////////////////////////////////////////
  4613. // DAODBEngine helpers
  4614. void AFXAPI AfxDaoInit()
  4615. {
  4616. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  4617. // Attempt to initialize OLE component objects
  4618. // (use default IMalloc allocator)
  4619. DAO_CHECK_ERROR(::CoInitialize(NULL),
  4620. AFX_DAO_ERROR_ENGINE_INITIALIZATION);
  4621. pDaoState->m_bOleInitialized = TRUE;
  4622. // Hook AfxDaoTerm to CWinApp, otherwise explicit AfxDaoTerm call req'd
  4623. CWinApp* pApp = AfxGetApp();
  4624. if (pApp != NULL)
  4625. pApp->m_lpfnDaoTerm = AfxDaoTerm;
  4626. BYTE bUseDao = _AfxDetermineDaoVersion();
  4627. CLSID clsidEngine;
  4628. COleVariant varKey;
  4629. GUID guidEngine;
  4630. // Set the interface type
  4631. #ifdef _UNICODE
  4632. guidEngine = IID_IDAODBEngineW;
  4633. #else
  4634. guidEngine = IID_IDAODBEngine;
  4635. #endif
  4636. // DAO 3.5 and 3.6 runtime key
  4637. varKey = _T("mbmabptebkjcdlgtjmskjwtsdhjbmkmwtrak");
  4638. switch (bUseDao)
  4639. {
  4640. case 35:
  4641. // Use DAO 3.5
  4642. clsidEngine = CLSID35_CDAODBEngine;
  4643. break;
  4644. case 30:
  4645. // Use DAO 3.0
  4646. clsidEngine = CLSID30_CDAODBEngine;
  4647. // DAO 3.0 runtime key
  4648. varKey = _T("mjgcqcejfchcijecpdhckcdjqigdejfccjri");
  4649. // Set the interface type
  4650. #ifdef _UNICODE
  4651. guidEngine = IID30_IDAODBEngineW;
  4652. #else
  4653. guidEngine = IID30_IDAODBEngine;
  4654. #endif
  4655. break;
  4656. case 36:
  4657. // Use DAO 3.6
  4658. clsidEngine = CLSID_CDAODBEngine;
  4659. break;
  4660. default:
  4661. ASSERT(FALSE);
  4662. }
  4663. LPCLASSFACTORY2 pCF2;
  4664. DAO_CHECK_ERROR(::CoGetClassObject(clsidEngine,
  4665. CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory2, (LPVOID*)&pCF2),
  4666. AFX_DAO_ERROR_ENGINE_INITIALIZATION);
  4667. TRY
  4668. {
  4669. DAO_CHECK_ERROR(pCF2->CreateInstanceLic( NULL, NULL, guidEngine,
  4670. V_BSTR(&varKey), (LPVOID*)&pDaoState->m_pDAODBEngine),
  4671. AFX_DAO_ERROR_ENGINE_INITIALIZATION);
  4672. }
  4673. CATCH_ALL(e)
  4674. {
  4675. pCF2->Release();
  4676. THROW_LAST();
  4677. }
  4678. END_CATCH_ALL
  4679. pCF2->Release();
  4680. }
  4681. DAODBEngine* AFXAPI AfxDaoGetEngine()
  4682. {
  4683. // Return DAODBEngine object for direct access
  4684. return AfxGetDaoState()->m_pDAODBEngine;
  4685. }
  4686. void AFXAPI AfxDaoTerm()
  4687. {
  4688. _AFX_DAO_STATE* pDaoState = AfxGetDaoState();
  4689. // Close any CDaoWorkspaces left around
  4690. void* pvKey;
  4691. void* pvObject;
  4692. POSITION pos = pDaoState->m_mapWorkspaces.GetStartPosition();
  4693. while (pos != NULL)
  4694. {
  4695. pDaoState->m_mapWorkspaces.GetNextAssoc(pos, pvKey, pvObject);
  4696. ((CDaoWorkspace*)pvObject)->Close();
  4697. }
  4698. pDaoState->m_mapWorkspaces.RemoveAll();
  4699. // Clean up engine object if necessary
  4700. if (pDaoState->m_pDAODBEngine != NULL)
  4701. {
  4702. pDaoState->m_pDAODBEngine->Release();
  4703. pDaoState->m_pDAODBEngine = NULL;
  4704. }
  4705. // Shutdown OLE component objects if necessary
  4706. if (pDaoState->m_bOleInitialized)
  4707. {
  4708. ::CoUninitialize();
  4709. pDaoState->m_bOleInitialized = FALSE;
  4710. }
  4711. // If hooked up to CWinApp, make sure to unhook
  4712. CWinApp* pApp = AfxGetApp();
  4713. if (pApp != NULL)
  4714. pApp->m_lpfnDaoTerm = NULL;
  4715. }
  4716. //////////////////////////////////////////////////////////////////////////////
  4717. // Inline function declarations expanded out-of-line
  4718. #ifndef _AFX_ENABLE_INLINES
  4719. static char _szAfxDaoInl[] = "afxdao.inl";
  4720. #undef THIS_FILE
  4721. #define THIS_FILE _szAfxDaoInl
  4722. #define _AFXDAOCORE_INLINE
  4723. #include "afxdao.inl"
  4724. #endif
  4725. #ifdef AFX_INIT_SEG
  4726. #pragma code_seg(AFX_INIT_SEG)
  4727. #endif
  4728. #pragma warning(disable: 4074)
  4729. #pragma init_seg(lib)
  4730. /////////////////////////////////////////////////////////////////////////////