Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1804 lines
45 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. Wsbdbent.cpp
  5. Abstract:
  6. The CWsbDbEntity and CWsbDbKey classes.
  7. Author:
  8. Ron White [ronw] 11-Dec-1996
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "wsbdbsys.h"
  13. #include "wsbdbkey.h"
  14. // Flags for binary search
  15. #define BIN_EQ 0x0001
  16. #define BIN_GT 0x0002
  17. #define BIN_LT 0x0004
  18. #define BIN_GTE (BIN_EQ | BIN_GT)
  19. #define BIN_LTE (BIN_EQ | BIN_LT)
  20. // Flags for CopyValues/GetValue/SetValue functions
  21. #define EV_DERIVED_DATA 0x0001
  22. #define EV_INDEX 0x0002
  23. #define EV_POS 0x0004
  24. #define EV_ASNEW 0x0008
  25. #define EV_USEKEY 0x0010
  26. #define EV_SEQNUM 0x0020
  27. #define EV_ALL 0xFFFF
  28. HRESULT
  29. CWsbDbEntity::Clone(
  30. IN REFIID riid,
  31. OUT void** ppEntity
  32. )
  33. /*++
  34. Implements:
  35. IWsbDbEntity::Clone
  36. --*/
  37. {
  38. HRESULT hr = S_OK;
  39. WsbTraceIn(OLESTR("CWsbDbEntity::Clone(IWsbEntity)"), OLESTR(""));
  40. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  41. m_SessionId, m_TableId);
  42. try {
  43. CLSID clsid;
  44. CComPtr<IWsbDbEntity> pEntity;
  45. CComPtr<IWsbDbEntityPriv> pEntityPriv;
  46. CComPtr<IPersistStream> pIPersistStream;
  47. IUnknown* pIUnknown;
  48. WsbAssert(0 != ppEntity, E_POINTER);
  49. // Create a new entity instance.
  50. pIUnknown = (IUnknown *)(IWsbPersistable *)(CWsbCollectable *)this;
  51. WsbAffirmHr(pIUnknown->QueryInterface(IID_IPersistStream,
  52. (void**) &pIPersistStream));
  53. WsbAffirmHr(pIPersistStream->GetClassID(&clsid));
  54. WsbAffirmHr(CoCreateInstance(clsid, NULL, CLSCTX_ALL,
  55. IID_IWsbDbEntity, (void**) &pEntity));
  56. WsbAffirmHr(pEntity->QueryInterface(IID_IWsbDbEntityPriv,
  57. (void**)&pEntityPriv))
  58. // Initialize the clone
  59. if (m_pDb) {
  60. WsbAffirmHr(pEntityPriv->Init(m_pDb, m_pDbSys, m_RecInfo.Type, m_SessionId));
  61. }
  62. // Copy data into the clone
  63. WsbAffirmHr(pEntityPriv->CopyValues(EV_ALL, this));
  64. // Get the requested interface
  65. WsbAffirmHr(pEntity->QueryInterface(riid, (void**)ppEntity));
  66. } WsbCatch(hr);
  67. WsbTraceOut(OLESTR("CWsbDbEntity::Clone(IWbEntity)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  68. return(hr);
  69. }
  70. HRESULT
  71. CWsbDbEntity::Copy(
  72. IWsbDbEntity* pEntity
  73. )
  74. /*++
  75. Implements:
  76. IWsbDbEntityPriv::Copy
  77. Comments:
  78. Copy the data in the derived object.
  79. --*/
  80. {
  81. HRESULT hr = S_OK;
  82. WsbTraceIn(OLESTR("CWsbDbEntity::Copy(IWsbDbEntity)"), OLESTR(""));
  83. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  84. m_SessionId, m_TableId);
  85. try {
  86. HGLOBAL hMem;
  87. CComPtr<IPersistStream> pIPersistStream1;
  88. CComPtr<IPersistStream> pIPersistStream2;
  89. CComPtr<IStream> pIStream;
  90. IUnknown* pIUnknown;
  91. WsbAssert(0 != pEntity, E_POINTER);
  92. // Get PersistStream interfaces for myself
  93. pIUnknown = (IUnknown *)(IWsbPersistable *)(CWsbCollectable *)this;
  94. WsbAffirmHr(pIUnknown->QueryInterface(IID_IPersistStream, (void**) &pIPersistStream1));
  95. WsbAffirmHr(pEntity->QueryInterface(IID_IPersistStream, (void**) &pIPersistStream2));
  96. // Create a memory stream
  97. WsbAffirmHr(getMem(&hMem));
  98. WsbAffirmHr(CreateStreamOnHGlobal(hMem, FALSE, &pIStream));
  99. // Save the other entity to the stream
  100. WsbAffirmHr(pIPersistStream2->Save(pIStream, FALSE));
  101. pIStream = 0;
  102. // Load myself from the memory
  103. WsbAffirmHr(fromMem(hMem));
  104. GlobalFree(hMem);
  105. SetIsDirty(TRUE);
  106. } WsbCatch(hr);
  107. WsbTraceOut(OLESTR("CWsbDbEntity::Copy(IWbEntity)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  108. return(hr);
  109. }
  110. HRESULT
  111. CWsbDbEntity::CopyValues(
  112. ULONG flags,
  113. IWsbDbEntity* pEntity
  114. )
  115. /*++
  116. Implements:
  117. IWsbDbEntityPriv::CopyValues
  118. Comments:
  119. Selectively copy some DBEntity values from one entity to another.
  120. --*/
  121. {
  122. HRESULT hr = S_OK;
  123. WsbTraceIn(OLESTR("CWsbDbEntity::CopyValues(IWsbEntity)"), OLESTR(""));
  124. try {
  125. ULONG value;
  126. CComPtr<IWsbDbEntityPriv> pEntityPriv;
  127. // Copy derived data
  128. if (flags & EV_DERIVED_DATA) {
  129. WsbAffirmHr(Copy(pEntity));
  130. }
  131. WsbAffirmHr(pEntity->QueryInterface(IID_IWsbDbEntityPriv,
  132. (void**)&pEntityPriv));
  133. // Copy DbEntity specific data
  134. if (flags & EV_USEKEY) {
  135. WsbAffirmHr(pEntityPriv->GetValue(EV_USEKEY, &value));
  136. if (m_pKeyInfo[m_UseKeyIndex].Type != value) {
  137. WsbAffirmHr(UseKey(value));
  138. }
  139. }
  140. if (flags & EV_SEQNUM) {
  141. WsbAffirmHr(pEntityPriv->GetValue(EV_SEQNUM, &value));
  142. m_SeqNum = (LONG)value;
  143. }
  144. if (flags & EV_ASNEW) {
  145. WsbAffirmHr(pEntityPriv->GetValue(EV_ASNEW, &value));
  146. if (value) {
  147. WsbAffirmHr(MarkAsNew());
  148. }
  149. }
  150. SetIsDirty(TRUE);
  151. } WsbCatch(hr);
  152. WsbTraceOut(OLESTR("CWsbDbEntity::CopyValues(IWbEntity)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  153. return(hr);
  154. }
  155. HRESULT
  156. CWsbDbEntity::Disconnect(
  157. void
  158. )
  159. /*++
  160. Implements:
  161. IWsbDbEntityPriv::Disconnect
  162. Comments:
  163. Disconnect the entity from its database (to reduce the DBs
  164. reference count).
  165. --*/
  166. {
  167. HRESULT hr = S_OK;
  168. WsbTraceIn(OLESTR("CWsbDbEntity::Disconnect()"), OLESTR(""));
  169. try {
  170. if (m_pDb) {
  171. // WsbAffirmHr(m_pDb->Release());
  172. m_pDb = NULL; // Release is automatic
  173. }
  174. } WsbCatch(hr);
  175. WsbTraceOut(OLESTR("CWsbDbEntity::Disconnect()"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  176. return(hr);
  177. }
  178. HRESULT
  179. CWsbDbEntity::GetCurKey(
  180. IWsbDbKey** ppKey
  181. )
  182. /*++
  183. Implements:
  184. IWsbDbEntityPriv::GetCurKey
  185. Comments:
  186. Return the current key.
  187. --*/
  188. {
  189. HRESULT hr = S_OK;
  190. WsbTraceIn(OLESTR("CWsbDbEntity::GetCurKey"), OLESTR(""));
  191. try {
  192. ULONG kType = 0;
  193. if (m_pKeyInfo) {
  194. kType = m_pKeyInfo[m_UseKeyIndex].Type;
  195. }
  196. WsbAffirmHr(GetKey(kType, ppKey));
  197. } WsbCatch(hr);
  198. WsbTraceOut(OLESTR("CWsbDbEntity::GetCurKey(IWbEntity)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  199. return(hr);
  200. }
  201. HRESULT
  202. CWsbDbEntity::GetKey(
  203. ULONG KeyType,
  204. IWsbDbKey** ppKey
  205. )
  206. /*++
  207. Implements:
  208. IWsbDbEntityPriv::GetKey
  209. Comments:
  210. Return the specified key.
  211. --*/
  212. {
  213. HRESULT hr = S_OK;
  214. WsbTraceIn(OLESTR("CWsbDbEntity::GetKey"), OLESTR(""));
  215. try {
  216. CComPtr<IWsbDbKey> pKey;
  217. CComPtr<IWsbDbKeyPriv> pKeyPriv;
  218. WsbAssert(0 != ppKey, E_POINTER);
  219. WsbAffirmHr(CoCreateInstance(CLSID_CWsbDbKey, 0, CLSCTX_SERVER,
  220. IID_IWsbDbKey, (void **)&pKey ));
  221. WsbAffirmHr(pKey->QueryInterface(IID_IWsbDbKeyPriv,
  222. (void**)&pKeyPriv));
  223. WsbAffirmHr(pKeyPriv->SetType(KeyType));
  224. WsbAffirmHr(UpdateKey(pKey));
  225. *ppKey = pKey;
  226. (*ppKey)->AddRef();
  227. } WsbCatch(hr);
  228. WsbTraceOut(OLESTR("CWsbDbEntity::GetKey(IWbEntity)"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  229. return(hr);
  230. }
  231. HRESULT
  232. CWsbDbEntity::FindEQ(
  233. void
  234. )
  235. /*++
  236. Implements:
  237. IWsbDbEntity::FindEQ
  238. --*/
  239. {
  240. HRESULT hr = S_OK;
  241. CComPtr<IWsbDbPriv> pDbImp;
  242. WsbTraceIn(OLESTR("CWsbDbEntity::FindEQ"), OLESTR(""));
  243. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  244. m_SessionId, m_TableId);
  245. try {
  246. CComPtr<IWsbDbEntity> pEntity;
  247. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  248. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  249. WsbAffirmHr(pDbImp->Lock());
  250. WsbAffirmHr(jet_seek(JET_bitSeekEQ));
  251. WsbAffirmHr(jet_get_data());
  252. } WsbCatch(hr);
  253. if (pDbImp) {
  254. WsbAffirmHr(pDbImp->Unlock());
  255. }
  256. WsbTraceOut(OLESTR("CWsbDbEntity::FindEQ"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  257. return(hr);
  258. }
  259. HRESULT
  260. CWsbDbEntity::FindGT(
  261. void
  262. )
  263. /*++
  264. Implements:
  265. IWsbDbEntity::FindGT
  266. --*/
  267. {
  268. HRESULT hr = S_OK;
  269. CComPtr<IWsbDbPriv> pDbImp;
  270. WsbTraceIn(OLESTR("CWsbDbEntity::FindGT"), OLESTR(""));
  271. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  272. m_SessionId, m_TableId);
  273. try {
  274. CComPtr<IWsbDbEntity> pEntity;
  275. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  276. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  277. WsbAffirmHr(pDbImp->Lock());
  278. WsbAffirmHr(jet_seek(JET_bitSeekGT));
  279. WsbAffirmHr(jet_get_data());
  280. } WsbCatch(hr);
  281. if (pDbImp) {
  282. WsbAffirmHr(pDbImp->Unlock());
  283. }
  284. WsbTraceOut(OLESTR("CWsbDbEntity::FindGT"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  285. return(hr);
  286. }
  287. HRESULT
  288. CWsbDbEntity::FindGTE(
  289. void
  290. )
  291. /*++
  292. Implements:
  293. IWsbDbEntity::FindGTE
  294. --*/
  295. {
  296. HRESULT hr = S_OK;
  297. CComPtr<IWsbDbPriv> pDbImp;
  298. WsbTraceIn(OLESTR("CWsbDbEntity::FindGTE"), OLESTR(""));
  299. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  300. m_SessionId, m_TableId);
  301. try {
  302. CComPtr<IWsbDbEntity> pEntity;
  303. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  304. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  305. WsbAffirmHr(pDbImp->Lock());
  306. WsbAffirmHr(jet_seek(JET_bitSeekGE));
  307. WsbAffirmHr(jet_get_data());
  308. } WsbCatch(hr);
  309. if (pDbImp) {
  310. WsbAffirmHr(pDbImp->Unlock());
  311. }
  312. WsbTraceOut(OLESTR("CWsbDbEntity::FindGTE"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  313. return(hr);
  314. }
  315. HRESULT
  316. CWsbDbEntity::FindLT(
  317. void
  318. )
  319. /*++
  320. Implements:
  321. IWsbDbEntity::FindLT
  322. --*/
  323. {
  324. HRESULT hr = S_OK;
  325. CComPtr<IWsbDbPriv> pDbImp;
  326. WsbTraceIn(OLESTR("CWsbDbEntity::FindLT"), OLESTR(""));
  327. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  328. m_SessionId, m_TableId);
  329. try {
  330. CComPtr<IWsbDbEntity> pEntity;
  331. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  332. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  333. WsbAffirmHr(pDbImp->Lock());
  334. WsbAffirmHr(jet_seek(JET_bitSeekLT));
  335. WsbAffirmHr(jet_get_data());
  336. } WsbCatch(hr);
  337. if (pDbImp) {
  338. WsbAffirmHr(pDbImp->Unlock());
  339. }
  340. WsbTraceOut(OLESTR("CWsbDbEntity::FindLT"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  341. return(hr);
  342. }
  343. HRESULT
  344. CWsbDbEntity::FindLTE(
  345. void
  346. )
  347. /*++
  348. Implements:
  349. IWsbDbEntity::FindLTE
  350. --*/
  351. {
  352. HRESULT hr = S_OK;
  353. CComPtr<IWsbDbPriv> pDbImp;
  354. WsbTraceIn(OLESTR("CWsbDbEntity::FindLTE"), OLESTR(""));
  355. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  356. m_SessionId, m_TableId);
  357. try {
  358. CComPtr<IWsbDbEntity> pEntity;
  359. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  360. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  361. WsbAffirmHr(pDbImp->Lock());
  362. WsbAffirmHr(jet_seek(JET_bitSeekLE));
  363. WsbAffirmHr(jet_get_data());
  364. } WsbCatch(hr);
  365. if (pDbImp) {
  366. WsbAffirmHr(pDbImp->Unlock());
  367. }
  368. WsbTraceOut(OLESTR("CWsbDbEntity::FindLTE"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  369. return(hr);
  370. }
  371. HRESULT
  372. CWsbDbEntity::First(
  373. void
  374. )
  375. /*++
  376. Implements:
  377. IWsbDbEntity::First.
  378. --*/
  379. {
  380. HRESULT hr = S_OK;
  381. CComPtr<IWsbDbPriv> pDbImp;
  382. WsbTraceIn(OLESTR("CWsbDbEntity::First"), OLESTR(""));
  383. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  384. m_SessionId, m_TableId);
  385. try {
  386. CComPtr<IWsbDbEntity> pEntity;
  387. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  388. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  389. WsbAffirmHr(pDbImp->Lock());
  390. WsbAffirmHr(jet_move(JET_MoveFirst));
  391. WsbAffirmHr(jet_get_data());
  392. m_SaveAsNew = FALSE;
  393. } WsbCatch(hr);
  394. if (pDbImp) {
  395. WsbAffirmHr(pDbImp->Unlock());
  396. }
  397. WsbTraceOut(OLESTR("CWsbDbEntity::First"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  398. return(hr);
  399. }
  400. HRESULT
  401. CWsbDbEntity::GetValue(
  402. ULONG flag,
  403. ULONG* pValue
  404. )
  405. /*++
  406. Implements:
  407. IWsbDbEntityPriv::GetValue
  408. Comments:
  409. Get a specific (based on flag) value from a DBEntity.
  410. --*/
  411. {
  412. HRESULT hr = S_OK;
  413. WsbTraceIn(OLESTR("CWsbDbEntity::GetValue"), OLESTR(""));
  414. try {
  415. switch (flag) {
  416. case EV_INDEX:
  417. break;
  418. case EV_POS:
  419. break;
  420. case EV_ASNEW:
  421. *pValue = m_SaveAsNew;
  422. break;
  423. case EV_USEKEY:
  424. *pValue = m_pKeyInfo[m_UseKeyIndex].Type;
  425. break;
  426. case EV_SEQNUM:
  427. *pValue = (ULONG)m_SeqNum;
  428. break;
  429. }
  430. } WsbCatch(hr);
  431. WsbTraceOut(OLESTR("CWsbDbEntity::GetValue"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  432. return(hr);
  433. }
  434. HRESULT
  435. CWsbDbEntity::SetSequentialScan(
  436. void
  437. )
  438. /*++
  439. Implements:
  440. IWsbDbEntity::SetSequentialScan.
  441. --*/
  442. {
  443. HRESULT hr = S_OK;
  444. WsbTraceIn(OLESTR("CWsbDbEntity::SetSequentialScan"), OLESTR(""));
  445. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"), m_SessionId, m_TableId);
  446. try {
  447. JET_ERR jstat = JET_errSuccess;
  448. // Set to sequential traversing
  449. jstat = JetSetTableSequential(m_SessionId, m_TableId, 0);
  450. WsbAffirmHr(jet_error(jstat));
  451. m_Sequential = TRUE;
  452. } WsbCatch(hr);
  453. WsbTraceOut(OLESTR("CWsbDbEntity::SetSequentialScan"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  454. return(hr);
  455. }
  456. HRESULT
  457. CWsbDbEntity::ResetSequentialScan(
  458. void
  459. )
  460. /*++
  461. Implements:
  462. IWsbDbEntity::ResetSequentialScan.
  463. --*/
  464. {
  465. HRESULT hr = S_OK;
  466. WsbTraceIn(OLESTR("CWsbDbEntity::ResetSequentialScan"), OLESTR(""));
  467. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"), m_SessionId, m_TableId);
  468. try {
  469. JET_ERR jstat = JET_errSuccess;
  470. // Set to sequential traversing
  471. jstat = JetResetTableSequential(m_SessionId, m_TableId, 0);
  472. WsbAffirmHr(jet_error(jstat));
  473. m_Sequential = FALSE;
  474. } WsbCatch(hr);
  475. WsbTraceOut(OLESTR("CWsbDbEntity::ResetSequentialScan"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  476. return(hr);
  477. }
  478. HRESULT
  479. CWsbDbEntity::Init(
  480. IN IWsbDb* pDb,
  481. IN IWsbDbSys *pDbSys,
  482. IN ULONG RecType,
  483. IN JET_SESID SessionId
  484. )
  485. /*++
  486. Implements:
  487. IWsbDbEntity::Init
  488. --*/
  489. {
  490. HRESULT hr = S_OK;
  491. WsbTraceIn(OLESTR("CWsbDbEntity::Init"), OLESTR(""));
  492. try {
  493. WsbAssert(0 != pDb, E_POINTER);
  494. WsbAssert(0 != pDbSys, E_POINTER);
  495. // Don't allow DB Sys switch
  496. if (pDbSys != m_pDbSys) {
  497. m_pDbSys = pDbSys; // Automatic AddRef() on Db Sys object
  498. }
  499. // Don't allow DB switch
  500. if (pDb != m_pDb) {
  501. CComPtr<IWsbDbPriv> pDbImp;
  502. // CComQIPtr<IWsbDbSessionPriv, &IID_IWsbDbSessionPriv> pSessionPriv = pSession;
  503. WsbAssert(m_pDb == 0, WSB_E_INVALID_DATA);
  504. m_pDb = pDb; // Automatic AddRef() on Db object
  505. // WsbAssertHr(pSessionPriv->GetJetId(&m_Session));
  506. // Get info about myself from the IDB object
  507. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  508. WsbAffirmHr(pDbImp->GetRecInfo(RecType, &m_RecInfo));
  509. WsbAssert(m_RecInfo.nKeys > 0, E_INVALIDARG);
  510. // Get info about my keys
  511. m_pKeyInfo = (COM_IDB_KEY_INFO*)WsbAlloc(sizeof(COM_IDB_KEY_INFO) *
  512. m_RecInfo.nKeys);
  513. WsbAffirmHr(pDbImp->GetKeyInfo(RecType, m_RecInfo.nKeys, m_pKeyInfo));
  514. // Get the maximum amount of memory need to hold a streamed
  515. // copy of the user data
  516. // ULONG minSize;
  517. // WsbAffirmHr(pDbImp->GetRecSize(m_RecInfo.Type, &minSize, &m_RecInfo.MaxSize));
  518. m_SeqNum = -1;
  519. m_PosOk = FALSE;
  520. m_SessionId = SessionId;
  521. // Get Jet IDs (and a new table ID unique to this entity)
  522. WsbAffirmHr(pDbImp->GetJetIds(m_SessionId, m_RecInfo.Type,
  523. &m_TableId, &m_ColId));
  524. WsbAffirmHr(getMem(&m_hMem));
  525. // Set the first key as the default
  526. UseKey(m_pKeyInfo[0].Type);
  527. }
  528. } WsbCatch(hr);
  529. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  530. m_SessionId, m_TableId);
  531. WsbTraceOut(OLESTR("CWsbDbEntity::Init"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  532. return(hr);
  533. }
  534. HRESULT
  535. CWsbDbEntity::Last(
  536. void
  537. )
  538. /*++
  539. Implements:
  540. IWsbDbEntity::Last.
  541. --*/
  542. {
  543. HRESULT hr = S_OK;
  544. CComPtr<IWsbDbPriv> pDbImp;
  545. WsbTraceIn(OLESTR("CWsbDbEntity::Last"), OLESTR(""));
  546. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  547. m_SessionId, m_TableId);
  548. try {
  549. CComPtr<IWsbDbEntity> pEntity;
  550. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  551. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  552. WsbAffirmHr(pDbImp->Lock());
  553. WsbAffirmHr(jet_move(JET_MoveLast));
  554. WsbAffirmHr(jet_get_data());
  555. m_SaveAsNew = FALSE;
  556. } WsbCatch(hr);
  557. if (pDbImp) {
  558. WsbAffirmHr(pDbImp->Unlock());
  559. }
  560. WsbTraceOut(OLESTR("CWsbDbEntity::Last"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  561. return(hr);
  562. }
  563. HRESULT
  564. CWsbDbEntity::MarkAsNew(
  565. void
  566. )
  567. /*++
  568. Implements:
  569. IWsbDbEntity::MarkAsNew
  570. --*/
  571. {
  572. HRESULT hr = S_OK;
  573. WsbTraceIn(OLESTR("CWsbDbEntity::MarkAsNew"), OLESTR(""));
  574. try {
  575. m_SaveAsNew = TRUE;
  576. m_SeqNum = -1;
  577. m_PosOk = FALSE;
  578. SetIsDirty(TRUE);
  579. } WsbCatch(hr);
  580. WsbTraceOut(OLESTR("CWsbDbEntity::MarkAsNew"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  581. return(hr);
  582. }
  583. HRESULT
  584. CWsbDbEntity::Next(
  585. void
  586. )
  587. /*++
  588. Implements:
  589. IWsbDbEntity::Next.
  590. --*/
  591. {
  592. HRESULT hr = S_OK;
  593. CComPtr<IWsbDbPriv> pDbImp;
  594. WsbTraceIn(OLESTR("CWsbDbEntity::Next"), OLESTR(""));
  595. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  596. m_SessionId, m_TableId);
  597. try {
  598. CComPtr<IWsbDbEntity> pEntity;
  599. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  600. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  601. WsbAffirmHr(pDbImp->Lock());
  602. WsbAffirmHr(jet_make_current());
  603. WsbAffirmHr(jet_move(JET_MoveNext));
  604. WsbAffirmHr(jet_get_data());
  605. m_SaveAsNew = FALSE;
  606. } WsbCatch(hr);
  607. if (pDbImp) {
  608. WsbAffirmHr(pDbImp->Unlock());
  609. }
  610. WsbTraceOut(OLESTR("CWsbDbEntity::Next"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  611. return(hr);
  612. }
  613. HRESULT
  614. CWsbDbEntity::Previous(
  615. void
  616. )
  617. /*++
  618. Implements:
  619. IWsbDbEntity::Previous.
  620. --*/
  621. {
  622. HRESULT hr = S_OK;
  623. CComPtr<IWsbDbPriv> pDbImp;
  624. WsbTraceIn(OLESTR("CWsbDbEntity::Previous"), OLESTR(""));
  625. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  626. m_SessionId, m_TableId);
  627. try {
  628. CComPtr<IWsbDbEntity> pEntity;
  629. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  630. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  631. WsbAffirmHr(pDbImp->Lock());
  632. WsbAffirmHr(jet_make_current());
  633. WsbAffirmHr(jet_move(JET_MovePrevious));
  634. WsbAffirmHr(jet_get_data());
  635. m_SaveAsNew = FALSE;
  636. } WsbCatch(hr);
  637. if (pDbImp) {
  638. WsbAffirmHr(pDbImp->Unlock());
  639. }
  640. WsbTraceOut(OLESTR("CWsbDbEntity::Previous"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  641. return(hr);
  642. }
  643. HRESULT
  644. CWsbDbEntity::Print(
  645. IStream* pStream
  646. )
  647. /*++
  648. Implements:
  649. IWsbDbEntity::Print.
  650. --*/
  651. {
  652. HRESULT hr = S_OK;
  653. CComPtr<IWsbDbPriv> pDbImp;
  654. WsbTraceIn(OLESTR("CWsbDbEntity::Print"), OLESTR(""));
  655. try {
  656. CComPtr<IWsbDbEntity> pEntity;
  657. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  658. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  659. WsbAffirmHr(WsbPrintfToStream(pStream, OLESTR(" (IDB SeqNum = %6ld) "), m_SeqNum));
  660. } WsbCatch(hr);
  661. WsbTraceOut(OLESTR("CWsbDbEntity::Print"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  662. return(hr);
  663. }
  664. HRESULT
  665. CWsbDbEntity::Remove(
  666. void
  667. )
  668. /*++
  669. Implements:
  670. IWsbDbEntity::Remove
  671. --*/
  672. {
  673. HRESULT hr = S_OK;
  674. CComPtr<IWsbDbPriv> pDbImp;
  675. WsbTraceIn(OLESTR("CWsbDbEntity::Remove"), OLESTR(""));
  676. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  677. m_SessionId, m_TableId);
  678. try {
  679. CComPtr<IUnknown> pIUn;
  680. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  681. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  682. WsbAffirmHr(pDbImp->Lock());
  683. JET_ERR jstat;
  684. // Make sure this record is the current record.
  685. WsbAffirmHr(jet_make_current());
  686. // Delete the record
  687. jstat = JetDelete(m_SessionId, m_TableId);
  688. WsbAffirmHr(jet_error(jstat));
  689. CComQIPtr<IWsbDbSysPriv, &IID_IWsbDbSysPriv> pDbSysPriv = m_pDbSys;
  690. WsbAffirmPointer(pDbSysPriv);
  691. WsbAffirmHr(pDbSysPriv->IncrementChangeCount());
  692. } WsbCatch(hr);
  693. if (pDbImp) {
  694. WsbAffirmHr(pDbImp->Unlock());
  695. }
  696. WsbTraceOut(OLESTR("CWsbDbEntity::Remove"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  697. return(hr);
  698. }
  699. HRESULT
  700. CWsbDbEntity::SetValue(
  701. ULONG flag,
  702. ULONG value
  703. )
  704. /*++
  705. Implements:
  706. IWsbDbEntityPriv::SetValue
  707. Comments:
  708. Set a specific data value (base on flag).
  709. --*/
  710. {
  711. HRESULT hr = S_OK;
  712. WsbTraceIn(OLESTR("CWsbDbEntity::SetValue"), OLESTR(""));
  713. try {
  714. CComPtr<IWsbDbPriv> pDbImp;
  715. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  716. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  717. switch (flag) {
  718. case EV_INDEX:
  719. break;
  720. case EV_POS:
  721. break;
  722. case EV_ASNEW:
  723. if (value) {
  724. m_SaveAsNew = TRUE;
  725. } else {
  726. m_SaveAsNew = FALSE;
  727. }
  728. break;
  729. case EV_USEKEY:
  730. m_pKeyInfo[m_UseKeyIndex].Type = value;
  731. break;
  732. case EV_SEQNUM:
  733. m_SeqNum = (LONG)value;
  734. break;
  735. }
  736. } WsbCatch(hr);
  737. WsbTraceOut(OLESTR("CWsbDbEntity::SetValue"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  738. return(hr);
  739. }
  740. HRESULT
  741. CWsbDbEntity::UseKey(
  742. IN ULONG type
  743. )
  744. /*++
  745. Implements:
  746. IWsbDbEntity::UseKey
  747. --*/
  748. {
  749. HRESULT hr = S_OK;
  750. WsbTraceIn(OLESTR("CWsbDbEntity::UseKey"), OLESTR(""));
  751. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  752. m_SessionId, m_TableId);
  753. try {
  754. CComPtr<IWsbDbPriv> pDbImp;
  755. // Check that this is a valid key type
  756. for (int i = 0; i < m_RecInfo.nKeys; i++) {
  757. // Special case for type == 0; this means to use the
  758. // sequence number key
  759. if (0 == type) break;
  760. if (m_pKeyInfo[i].Type == type) break;
  761. }
  762. WsbAssert(i < m_RecInfo.nKeys, E_INVALIDARG);
  763. m_UseKeyIndex = (USHORT)i;
  764. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  765. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  766. size_t ilen;
  767. char * index_name_a;
  768. CWsbStringPtr index_name_w;
  769. JET_ERR jstat;
  770. WsbAffirmHr(index_name_w.Alloc(20));
  771. WsbAffirmHr(pDbImp->GetJetIndexInfo(m_SessionId, m_RecInfo.Type, type, NULL,
  772. &index_name_w, 20));
  773. ilen = wcslen(index_name_w);
  774. index_name_a = (char *)WsbAlloc(sizeof(WCHAR) * ilen + 1);
  775. WsbAffirm(0 != index_name_a, E_FAIL);
  776. WsbAffirm(0 < wcstombs(index_name_a, index_name_w, ilen + 1), E_FAIL);
  777. // Set the current index
  778. jstat = JetSetCurrentIndex(m_SessionId, m_TableId, index_name_a);
  779. WsbFree(index_name_a);
  780. WsbAffirmHr(jet_error(jstat));
  781. m_PosOk = FALSE;
  782. } WsbCatch(hr);
  783. WsbTraceOut(OLESTR("CWsbDbEntity::UseKey"), OLESTR(""));
  784. return(hr);
  785. }
  786. HRESULT
  787. CWsbDbEntity::Write(
  788. void
  789. )
  790. /*++
  791. Implements:
  792. IWsbDbEntity::Write
  793. --*/
  794. {
  795. HRESULT hr = S_OK;
  796. CComPtr<IWsbDbPriv> pDbImp;
  797. UCHAR temp_bytes1[IDB_MAX_KEY_SIZE + 4];
  798. WsbTraceIn(OLESTR("CWsbDbEntity::Write"), OLESTR("SaveAsNew = %ls"),
  799. WsbBoolAsString(m_SaveAsNew));
  800. JET_ERR jstat;
  801. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  802. m_SessionId, m_TableId);
  803. jstat = JetBeginTransaction(m_SessionId);
  804. WsbTrace(OLESTR("CWsbDbEntity::Write: JetBeginTransaction = %ld\n"), jstat);
  805. try {
  806. CComPtr<IWsbDbEntity> pEntity;
  807. CComPtr<IWsbDbEntityPriv> pEntityPriv;
  808. ULONG save_key_type;
  809. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  810. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  811. WsbAffirmHr(pDbImp->Lock());
  812. save_key_type = m_pKeyInfo[m_UseKeyIndex].Type;
  813. VOID* addr;
  814. ULONG Size;
  815. // Save the entity data to memory
  816. WsbAffirmHr(toMem(m_hMem, &Size));
  817. // Write the data to the current record
  818. addr = GlobalLock(m_hMem);
  819. WsbAffirm(addr, E_HANDLE);
  820. if (m_SaveAsNew) {
  821. jstat = JetPrepareUpdate(m_SessionId, m_TableId, JET_prepInsert);
  822. } else {
  823. // Make sure this record is the current record.
  824. WsbAffirmHr(jet_make_current());
  825. jstat = JetPrepareUpdate(m_SessionId, m_TableId, JET_prepReplace);
  826. }
  827. WsbAffirmHr(jet_error(jstat));
  828. WsbTrace(OLESTR("Setting binary record data\n"));
  829. jstat = JetSetColumn(m_SessionId, m_TableId, m_ColId, addr, Size,
  830. 0, NULL);
  831. WsbAffirmHr(jet_error(jstat));
  832. // Release the memory
  833. GlobalUnlock(m_hMem);
  834. // Set keys in current record
  835. for (int i = 0; i < m_RecInfo.nKeys; i++) {
  836. JET_COLUMNID col_id;
  837. BOOL do_set = FALSE;
  838. ULONG size;
  839. WsbAffirmHr(pDbImp->GetJetIndexInfo(m_SessionId, m_RecInfo.Type, m_pKeyInfo[i].Type,
  840. &col_id, NULL, 0));
  841. WsbAffirmHr(get_key(m_pKeyInfo[i].Type, temp_bytes1, &size));
  842. if (m_SaveAsNew) {
  843. do_set = TRUE;
  844. } else {
  845. HRESULT hrEqual;
  846. hrEqual = jet_compare_field(col_id, temp_bytes1, size);
  847. WsbAffirm(S_OK == hrEqual || S_FALSE == hrEqual, hrEqual);
  848. if (S_FALSE == hrEqual &&
  849. (m_pKeyInfo[i].Flags & IDB_KEY_FLAG_PRIMARY)) {
  850. // Changing the primary key is not allowed
  851. WsbThrow(WSB_E_IDB_PRIMARY_KEY_CHANGED);
  852. }
  853. do_set = (S_FALSE == hrEqual) ? TRUE : FALSE;
  854. }
  855. if (do_set) {
  856. WsbTrace(OLESTR("Setting key %ld\n"), m_pKeyInfo[i].Type);
  857. jstat = JetSetColumn(m_SessionId, m_TableId, col_id, temp_bytes1,
  858. size, 0, NULL);
  859. WsbAffirmHr(jet_error(jstat));
  860. }
  861. }
  862. // Insert/update the record
  863. WsbTrace(OLESTR("Updating/writing record\n"));
  864. jstat = JetUpdate(m_SessionId, m_TableId, NULL, 0, NULL);
  865. WsbAffirmHr(jet_error(jstat));
  866. CComQIPtr<IWsbDbSysPriv, &IID_IWsbDbSysPriv> pDbSysPriv = m_pDbSys;
  867. WsbAffirmPointer(pDbSysPriv);
  868. WsbAffirmHr(pDbSysPriv->IncrementChangeCount());
  869. m_SaveAsNew = FALSE;
  870. SetIsDirty(FALSE);
  871. } WsbCatch(hr);
  872. if (pDbImp) {
  873. WsbAffirmHr(pDbImp->Unlock());
  874. }
  875. if (SUCCEEDED(hr)) {
  876. jstat = JetCommitTransaction(m_SessionId, 0);
  877. WsbTrace(OLESTR("CWsbDbEntity::Write: JetCommitTransaction = %ld\n"), jstat);
  878. } else {
  879. jstat = JetRollback(m_SessionId, 0);
  880. WsbTrace(OLESTR("CWsbDbEntity::Write: JetRollback = %ld\n"), jstat);
  881. }
  882. WsbTraceOut(OLESTR("CWsbDbEntity::Write"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  883. return(hr);
  884. }
  885. HRESULT
  886. CWsbDbEntity::FinalConstruct(
  887. void
  888. )
  889. /*++
  890. Implements:
  891. CComObjectRoot::FinalConstruct
  892. --*/
  893. {
  894. HRESULT hr = S_OK;
  895. WsbTraceIn(OLESTR("CWsbDbEntity::FinalConstruct"), OLESTR("") );
  896. try {
  897. WsbAffirmHr(CWsbObject::FinalConstruct());
  898. m_pDb = NULL;
  899. m_SaveAsNew = FALSE;
  900. m_pKeyInfo = NULL;
  901. m_RecInfo.MaxSize = 0;
  902. m_SeqNum = -1;
  903. m_PosOk = FALSE;
  904. m_SessionId = 0;
  905. m_TableId = 0;
  906. m_hMem = 0;
  907. m_Sequential = FALSE;
  908. } WsbCatch(hr);
  909. WsbTraceOut(OLESTR("CWsbDbEntity::FinalConstruct"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  910. return(hr);
  911. }
  912. void
  913. CWsbDbEntity::FinalRelease(
  914. void
  915. )
  916. /*++
  917. Routine Description:
  918. This method does some cleanup of the object that is necessary
  919. during destruction.
  920. Arguments:
  921. None.
  922. Return Value:
  923. None.
  924. --*/
  925. {
  926. HRESULT hr = S_OK;
  927. WsbTraceIn(OLESTR("CWsbDbEntity::FinalRelease"), OLESTR(""));
  928. WsbTrace(OLESTR("DbEntity SessionId = %lx, TableId = %ld\n"),
  929. m_SessionId, m_TableId);
  930. try {
  931. if (m_hMem) {
  932. GlobalFree(m_hMem);
  933. }
  934. if (m_SessionId && m_TableId) {
  935. if (m_Sequential) {
  936. (void)ResetSequentialScan();
  937. }
  938. m_SessionId = 0;
  939. m_TableId = 0;
  940. }
  941. if (m_pDb) {
  942. // Release IDB objects
  943. m_pDb = 0;
  944. m_pDbSys = 0;
  945. }
  946. if (m_pKeyInfo) {
  947. WsbFree(m_pKeyInfo);
  948. m_pKeyInfo = NULL;
  949. }
  950. CWsbObject::FinalRelease();
  951. } WsbCatch(hr);
  952. WsbTraceOut(OLESTR("CWsbDbEntity::FinalRelease"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  953. }
  954. HRESULT
  955. CWsbDbEntity::CompareTo(
  956. IN IUnknown* pCollectable,
  957. OUT SHORT* pResult
  958. )
  959. /*++
  960. Implements:
  961. IWsbCollectable::CompareTo
  962. --*/
  963. {
  964. HRESULT hr = S_FALSE;
  965. IWsbDbEntity* pEntity;
  966. WsbTraceIn(OLESTR("CWsbDbEntity::CompareTo"), OLESTR(""));
  967. try {
  968. // Did they give us a valid item to compare to?
  969. WsbAssert(0 != pCollectable, E_POINTER);
  970. // We need the IWsbDbEntity interface to get the value of the object.
  971. WsbAffirmHr(pCollectable->QueryInterface(IID_IWsbDbEntity, (void**) &pEntity));
  972. hr = compare(pEntity, pResult);
  973. } WsbCatch(hr);
  974. WsbTraceOut(OLESTR("CWsbDbEntity::CompareTo"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
  975. return(hr);
  976. }
  977. // CWsbDbEntity internal helper functions
  978. // compare - compare control key to control key of another entity
  979. HRESULT CWsbDbEntity::compare(IWsbDbEntity* pEntity, SHORT* pResult)
  980. {
  981. HRESULT hr = S_OK;
  982. WsbTraceIn(OLESTR("CWsbDbEntity::compare"), OLESTR(""));
  983. try {
  984. CComPtr<IWsbCollectable> pCollectable;
  985. CComPtr<IWsbDbEntityPriv> pEntityPriv;
  986. CComPtr<IWsbDbKey> pKey1;
  987. CComPtr<IWsbDbKey> pKey2;
  988. SHORT result;
  989. WsbAffirmHr(GetCurKey(&pKey1));
  990. WsbAffirmHr(pKey1->QueryInterface(IID_IWsbCollectable,
  991. (void**)&pCollectable));
  992. WsbAffirmHr(pEntity->QueryInterface(IID_IWsbDbEntityPriv,
  993. (void**)&pEntityPriv))
  994. WsbAffirmHr(pEntityPriv->GetCurKey(&pKey2));
  995. WsbAffirmHr(pCollectable->CompareTo(pKey2, &result));
  996. if (pResult) {
  997. *pResult = result;
  998. }
  999. } WsbCatch(hr);
  1000. WsbTraceOut(OLESTR("CWsbDbEntity::compare"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1001. return(hr);
  1002. }
  1003. // fromMem - load entity data from memory
  1004. HRESULT CWsbDbEntity::fromMem(HGLOBAL hMem)
  1005. {
  1006. HRESULT hr = S_OK;
  1007. WsbTraceIn(OLESTR("CWsbDbEntity::fromMem"), OLESTR(""));
  1008. try {
  1009. CComPtr<IPersistStream> pIPersistStream;
  1010. CComPtr<IStream> pIStream;
  1011. IUnknown* pIUnknown;
  1012. WsbAssert(0 != hMem, E_POINTER);
  1013. // Get PersistStream interfaces for myself
  1014. pIUnknown = (IUnknown *)(IWsbPersistable *)(CWsbCollectable *)this;
  1015. WsbAffirmHr(pIUnknown->QueryInterface(IID_IPersistStream,
  1016. (void**) &pIPersistStream));
  1017. // Create a memory stream
  1018. WsbAffirmHr(CreateStreamOnHGlobal(hMem, FALSE, &pIStream));
  1019. // Load myself from the stream
  1020. WsbAffirmHr(pIPersistStream->Load(pIStream));
  1021. } WsbCatch(hr);
  1022. WsbTraceOut(OLESTR("CWsbDbEntity::fromMem"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1023. return(hr);
  1024. }
  1025. // get_key - get the byte array & size for the given key
  1026. HRESULT CWsbDbEntity::get_key(ULONG key_type, UCHAR* bytes, ULONG* pSize)
  1027. {
  1028. HRESULT hr = S_OK;
  1029. try {
  1030. ULONG expected_size;
  1031. ULONG size;
  1032. if (0 != key_type) {
  1033. UCHAR* pbytes;
  1034. CComPtr<IWsbDbKey> pKey;
  1035. CComPtr<IWsbDbKeyPriv> pKeyPriv;
  1036. // Check that this is a valid key type
  1037. for (int i = 0; i < m_RecInfo.nKeys; i++) {
  1038. if (m_pKeyInfo[i].Type == key_type) break;
  1039. }
  1040. WsbAssert(i < m_RecInfo.nKeys, E_INVALIDARG);
  1041. WsbAssert(0 != bytes, E_POINTER);
  1042. // Create a key of the right type
  1043. WsbAffirmHr(CoCreateInstance(CLSID_CWsbDbKey, 0, CLSCTX_SERVER,
  1044. IID_IWsbDbKey, (void **)&pKey ));
  1045. WsbAffirmHr(pKey->QueryInterface(IID_IWsbDbKeyPriv,
  1046. (void**)&pKeyPriv));
  1047. WsbAffirmHr(pKeyPriv->SetType(key_type));
  1048. // Get the key's value from the derived code
  1049. WsbAffirmHr(UpdateKey(pKey));
  1050. // Convert key to bytes
  1051. pbytes = bytes;
  1052. WsbAffirmHr(pKeyPriv->GetBytes(&pbytes, &size));
  1053. expected_size = m_pKeyInfo[i].Size;
  1054. WsbAffirm(size <= expected_size, WSB_E_INVALID_DATA);
  1055. while (size < expected_size) {
  1056. // Fill with zeros
  1057. pbytes[size] = '\0';
  1058. size++;
  1059. }
  1060. // 0 == key_type
  1061. // This is a special case, allowed only for Jet, to
  1062. // get the sequence number as a key. We can't use
  1063. // WsbConvertToBytes because the bytes end up in the
  1064. // wrong order.
  1065. } else {
  1066. size = sizeof(m_SeqNum);
  1067. memcpy(bytes, (void*)&m_SeqNum, size);
  1068. }
  1069. if (pSize) {
  1070. *pSize = size;
  1071. }
  1072. } WsbCatch(hr);
  1073. return(hr);
  1074. }
  1075. // getMem - allocate enough memory for this entity
  1076. HRESULT CWsbDbEntity::getMem(HGLOBAL* phMem)
  1077. {
  1078. HRESULT hr = S_OK;
  1079. WsbTraceIn(OLESTR("CWsbDbEntity::getMem"), OLESTR(""));
  1080. try {
  1081. HGLOBAL hMem;
  1082. WsbAssert(0 != phMem, E_POINTER);
  1083. WsbAffirm(0 < m_RecInfo.MaxSize, WSB_E_NOT_INITIALIZED);
  1084. hMem = GlobalAlloc(GHND, m_RecInfo.MaxSize);
  1085. WsbAffirm(hMem, E_OUTOFMEMORY);
  1086. *phMem = hMem;
  1087. } WsbCatch(hr);
  1088. WsbTraceOut(OLESTR("CWsbDbEntity::getMem"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1089. return(hr);
  1090. }
  1091. // toMem - save this entity to memory
  1092. HRESULT CWsbDbEntity::toMem(HGLOBAL hMem, ULONG* pSize)
  1093. {
  1094. HRESULT hr = S_OK;
  1095. WsbTraceIn(OLESTR("CWsbDbEntity::toMem"), OLESTR(""));
  1096. try {
  1097. CComPtr<IPersistStream> pIPersistStream;
  1098. CComPtr<IStream> pIStream;
  1099. IUnknown* pIUnknown;
  1100. ULARGE_INTEGER seek_pos;
  1101. LARGE_INTEGER seek_pos_in;
  1102. WsbAssert(0 != hMem, E_POINTER);
  1103. WsbAssert(0 != pSize, E_POINTER);
  1104. // Get PersistStream interfaces for myself
  1105. pIUnknown = (IUnknown *)(IWsbPersistable *)(CWsbCollectable *)this;
  1106. WsbAffirmHr(pIUnknown->QueryInterface(IID_IPersistStream,
  1107. (void**) &pIPersistStream));
  1108. // Create a memory stream
  1109. WsbAffirmHr(CreateStreamOnHGlobal(hMem, FALSE, &pIStream));
  1110. // Save to the stream
  1111. WsbAffirmHr(pIPersistStream->Save(pIStream, FALSE));
  1112. // Get the size
  1113. seek_pos_in.QuadPart = 0;
  1114. WsbAffirmHr(pIStream->Seek(seek_pos_in, STREAM_SEEK_CUR, &seek_pos));
  1115. *pSize = seek_pos.LowPart;
  1116. } WsbCatch(hr);
  1117. WsbTraceOut(OLESTR("CWsbDbEntity::toMem"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1118. return(hr);
  1119. }
  1120. // jet_compare_field - compare a string of bytes to the a column
  1121. // value in the current Jet record
  1122. // Return S_OK for equal, S_FALSE for not equal, other for an error.
  1123. HRESULT
  1124. CWsbDbEntity::jet_compare_field(ULONG col_id, UCHAR* bytes, ULONG size)
  1125. {
  1126. VOID* addr = NULL;
  1127. HRESULT hr = S_OK;
  1128. WsbTraceIn(OLESTR("CWsbDbEntity::jet_compare_field"), OLESTR(""));
  1129. try {
  1130. ULONG actualSize;
  1131. JET_ERR jstat;
  1132. CComPtr<IWsbDbPriv> pDbImp;
  1133. // Get some Jet DB info
  1134. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  1135. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  1136. // Get the column value
  1137. addr = GlobalLock(m_hMem);
  1138. WsbAffirm(addr, E_HANDLE);
  1139. jstat = JetRetrieveColumn(m_SessionId, m_TableId, col_id, addr,
  1140. size, &actualSize, 0, NULL);
  1141. WsbAffirmHr(jet_error(jstat));
  1142. // Compare them
  1143. if (memcmp(bytes, addr, size)) {
  1144. hr = S_FALSE;
  1145. }
  1146. } WsbCatch(hr);
  1147. if (NULL != addr) {
  1148. GlobalUnlock(m_hMem);
  1149. }
  1150. WsbTraceOut(OLESTR("CWsbDbEntity::jet_compare_field"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1151. return(hr);
  1152. }
  1153. // jet_get_data - retrieve record data from the current Jet record
  1154. HRESULT
  1155. CWsbDbEntity::jet_get_data(void)
  1156. {
  1157. VOID* addr = NULL;
  1158. HRESULT hr = S_OK;
  1159. WsbTraceIn(OLESTR("CWsbDbEntity::jet_get_data"), OLESTR(""));
  1160. try {
  1161. ULONG actualSize;
  1162. JET_COLUMNID col_id;
  1163. JET_ERR jstat;
  1164. CComPtr<IWsbDbPriv> pDbImp;
  1165. // Get some Jet DB info
  1166. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  1167. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  1168. // Get data
  1169. addr = GlobalLock(m_hMem);
  1170. WsbAffirm(addr, E_HANDLE);
  1171. jstat = JetRetrieveColumn(m_SessionId, m_TableId, m_ColId, addr,
  1172. m_RecInfo.MaxSize, &actualSize, 0, NULL);
  1173. WsbAffirmHr(jet_error(jstat));
  1174. WsbAffirmHr(fromMem(m_hMem));
  1175. // Get the sequence number
  1176. WsbAffirmHr(pDbImp->GetJetIndexInfo(m_SessionId, m_RecInfo.Type, 0, &col_id, NULL, 0));
  1177. jstat = JetRetrieveColumn(m_SessionId, m_TableId, col_id, &m_SeqNum,
  1178. sizeof(m_SeqNum), &actualSize, 0, NULL);
  1179. WsbAffirmHr(jet_error(jstat));
  1180. } WsbCatch(hr);
  1181. if (NULL != addr) {
  1182. GlobalUnlock(m_hMem);
  1183. }
  1184. WsbTraceOut(OLESTR("CWsbDbEntity::jet_get_data"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1185. return(hr);
  1186. }
  1187. // jet_make_current - make sure this is the current Jet record
  1188. // NOTE: This function, despite its name, does not attempt to force
  1189. // the JET "cursor" to be on the correct record because this can mess
  1190. // up too many things that can't necessarily be controlled at this
  1191. // level. For one thing, if the current key allows duplicates, we can't
  1192. // be sure to get to the correct record using the index for that key.
  1193. // If we try to use the sequence number as the key, we'd then be using
  1194. // the wrong index if we do a Next or Previous. If the user code is
  1195. // doing a Write or Remove, it's better for that code to make sure via
  1196. // the Find functions that the cursor is position correctly.
  1197. HRESULT
  1198. CWsbDbEntity::jet_make_current(void)
  1199. {
  1200. HRESULT hr = S_OK;
  1201. WsbTraceIn(OLESTR("CWsbDbEntity::jet_make_current"), OLESTR(""));
  1202. try {
  1203. ULONG actualSize;
  1204. JET_COLUMNID col_id;
  1205. JET_ERR jstat;
  1206. CComPtr<IWsbDbPriv> pDbImp;
  1207. LONG seq_num;
  1208. // Get some Jet DB info
  1209. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  1210. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  1211. WsbAffirmHr(pDbImp->GetJetIndexInfo(m_SessionId, m_RecInfo.Type, 0, &col_id, NULL, 0));
  1212. // Make sure this record is still the current record.
  1213. // We do this by comparing the sequence numbers
  1214. jstat = JetRetrieveColumn(m_SessionId, m_TableId, col_id, &seq_num,
  1215. sizeof(seq_num), &actualSize, 0, NULL);
  1216. WsbAffirmHr(jet_error(jstat));
  1217. if (!m_PosOk || seq_num != m_SeqNum) {
  1218. WsbThrow(WSB_E_IDB_IMP_ERROR);
  1219. }
  1220. } WsbCatch(hr);
  1221. WsbTraceOut(OLESTR("CWsbDbEntity::jet_make_current"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1222. return(hr);
  1223. }
  1224. // jet_move - move current Jet record
  1225. HRESULT
  1226. CWsbDbEntity::jet_move(LONG pos)
  1227. {
  1228. HRESULT hr = S_OK;
  1229. WsbTraceIn(OLESTR("CWsbDbEntity::jet_move"), OLESTR(""));
  1230. try {
  1231. JET_ERR jstat;
  1232. CComPtr<IWsbDbPriv> pDbImp;
  1233. // Get some Jet DB info
  1234. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  1235. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  1236. // Do the move
  1237. jstat = JetMove(m_SessionId, m_TableId, pos, 0);
  1238. if (jstat == JET_errNoCurrentRecord) {
  1239. WsbThrow(WSB_E_NOTFOUND);
  1240. }
  1241. WsbAffirmHr(jet_error(jstat));
  1242. m_PosOk = TRUE;
  1243. } WsbCatch(hr);
  1244. WsbTraceOut(OLESTR("CWsbDbEntity::jet_move"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1245. return(hr);
  1246. }
  1247. // jet_seek - find Jet record based on current key and seek_flag;
  1248. // sets the current Jet record on success
  1249. HRESULT
  1250. CWsbDbEntity::jet_seek(ULONG seek_flag)
  1251. {
  1252. UCHAR temp_bytes1[IDB_MAX_KEY_SIZE + 4];
  1253. HRESULT hr = S_OK;
  1254. WsbTraceIn(OLESTR("CWsbDbEntity::jet_seek"), OLESTR(""));
  1255. try {
  1256. JET_ERR jstat;
  1257. CComPtr<IWsbDbPriv> pDbImp;
  1258. ULONG size;
  1259. // Get some Jet DB info
  1260. WsbAffirm(m_pDb, WSB_E_NOT_INITIALIZED);
  1261. WsbAffirmHr(m_pDb->QueryInterface(IID_IWsbDbPriv, (void**)&pDbImp));
  1262. // Get the current key & give it to Jet
  1263. WsbAffirmHr(get_key(m_pKeyInfo[m_UseKeyIndex].Type, temp_bytes1, &size));
  1264. jstat = JetMakeKey(m_SessionId, m_TableId, temp_bytes1, size,
  1265. JET_bitNewKey);
  1266. WsbAffirmHr(jet_error(jstat));
  1267. // Do the seek
  1268. jstat = JetSeek(m_SessionId, m_TableId, seek_flag);
  1269. if (jstat == JET_errRecordNotFound) {
  1270. WsbThrow(WSB_E_NOTFOUND);
  1271. } else if (jstat == JET_wrnSeekNotEqual) {
  1272. jstat = JET_errSuccess;
  1273. }
  1274. WsbAffirmHr(jet_error(jstat));
  1275. m_PosOk = TRUE;
  1276. } WsbCatch(hr);
  1277. WsbTraceOut(OLESTR("CWsbDbEntity::jet_seek"), OLESTR("hr =<%ls>"), WsbHrAsString(hr));
  1278. return(hr);
  1279. }