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

3428 lines
74 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File:
  6. //
  7. // Contents:
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "JetBlue.h"
  13. #include "locks.h"
  14. #ifdef USE_SINGLE_JET_CALL
  15. CCriticalSection g_JetCallLock;
  16. #define SINGLE_JET_CALL CCriticalSectionLocker lock(g_JetCallLock)
  17. #else
  18. #define SINGLE_JET_CALL
  19. #endif
  20. DWORD
  21. DeleteFilesInDirectory(
  22. IN LPTSTR szDir,
  23. IN LPTSTR szFilesToBeDelete,
  24. IN BOOL bIncludeSubdir
  25. )
  26. /*++
  27. --*/
  28. {
  29. TCHAR szFile[MAX_PATH+1];
  30. HANDLE hFile;
  31. WIN32_FIND_DATA findData;
  32. BOOL bSuccess = TRUE;
  33. DWORD dwStatus = ERROR_SUCCESS;
  34. if (lstrlen(szDir) + lstrlen(szFilesToBeDelete) + 2 > sizeof(szFile) / sizeof(TCHAR))
  35. {
  36. return ERROR_INVALID_DATA;
  37. }
  38. wsprintf(
  39. szFile,
  40. _TEXT("%s\\%s"),
  41. szDir,
  42. szFilesToBeDelete
  43. );
  44. hFile = FindFirstFile(
  45. szFile,
  46. &findData
  47. );
  48. if(hFile == INVALID_HANDLE_VALUE)
  49. {
  50. return GetLastError();
  51. }
  52. // _tprintf(_TEXT("Deleting %s\n"), szDir);
  53. while(bSuccess == TRUE)
  54. {
  55. if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && bIncludeSubdir == TRUE)
  56. {
  57. if( lstrcmp(findData.cFileName, _TEXT(".")) != 0 &&
  58. lstrcmp(findData.cFileName, _TEXT("..")) != 0 )
  59. {
  60. if (lstrlen(szDir) + lstrlen(findData.cFileName) + 2 <= sizeof(szFile) / sizeof(TCHAR))
  61. {
  62. wsprintf(szFile, _TEXT("%s\\%s"), szDir, findData.cFileName);
  63. bSuccess = DeleteFilesInDirectory(
  64. szFile,
  65. szFilesToBeDelete,
  66. bIncludeSubdir
  67. );
  68. }
  69. }
  70. }
  71. else
  72. {
  73. if (lstrlen(szDir) + lstrlen(findData.cFileName) + 2 <= sizeof(szFile) / sizeof(TCHAR))
  74. {
  75. wsprintf(
  76. szFile,
  77. _TEXT("%s\\%s"),
  78. szDir,
  79. findData.cFileName
  80. );
  81. bSuccess = DeleteFile(szFile);
  82. }
  83. }
  84. if(bSuccess == TRUE)
  85. {
  86. // return FALSE with error code set to ERROR_NO_MORE_FILES
  87. bSuccess = FindNextFile(hFile, &findData);
  88. }
  89. }
  90. dwStatus = GetLastError();
  91. FindClose(hFile);
  92. return (dwStatus == ERROR_NO_MORE_FILES) ? ERROR_SUCCESS : dwStatus;
  93. }
  94. //----------------------------------------------------------------
  95. JET_ERR
  96. ConvertTLSJbColumnDefToJbColumnCreate(
  97. IN const PTLSJBColumn pTlsJbColumn,
  98. IN OUT JET_COLUMNCREATE* pJetColumnCreate
  99. )
  100. /*
  101. */
  102. {
  103. pJetColumnCreate->cbStruct = sizeof(JET_COLUMNCREATE);
  104. if(ConvertWstrToJBstr(pTlsJbColumn->pszColumnName, &pJetColumnCreate->szColumnName) == FALSE)
  105. {
  106. return JET_errInvalidParameter;
  107. }
  108. pJetColumnCreate->coltyp = pTlsJbColumn->colType;
  109. pJetColumnCreate->cbMax = pTlsJbColumn->cbMaxLength;
  110. pJetColumnCreate->grbit = pTlsJbColumn->jbGrbit;
  111. pJetColumnCreate->pvDefault = pTlsJbColumn->pbDefValue;
  112. pJetColumnCreate->cbDefault = pTlsJbColumn->cbDefValue;
  113. pJetColumnCreate->cp = pTlsJbColumn->colCodePage;
  114. return JET_errSuccess;
  115. }
  116. //----------------------------------------------------------------
  117. JET_ERR
  118. ConvertTlsJBTableIndexDefToJbIndexCreate(
  119. IN const PTLSJBIndex pTlsJbTableIndex,
  120. IN OUT JET_INDEXCREATE* pJetIndexCreate
  121. )
  122. /*
  123. */
  124. {
  125. JET_ERR jetError = JET_errSuccess;
  126. DWORD count=0;
  127. pJetIndexCreate->cbStruct = sizeof(JET_INDEXCREATE);
  128. if(ConvertWstrToJBstr(pTlsJbTableIndex->pszIndexName, &pJetIndexCreate->szIndexName) == FALSE)
  129. {
  130. jetError = JET_errInvalidParameter;
  131. goto cleanup;
  132. }
  133. if(pTlsJbTableIndex->pszIndexKey && pTlsJbTableIndex->cbKey == 0)
  134. {
  135. count++;
  136. // need double NULL terminate
  137. while(pTlsJbTableIndex->pszIndexKey[count] != _TEXT('\0') ||
  138. pTlsJbTableIndex->pszIndexKey[count-1] != _TEXT('\0'))
  139. {
  140. //
  141. // this max. is pseudo impose.
  142. //
  143. if(count >= TLS_JETBLUE_MAX_INDEXKEY_LENGTH)
  144. {
  145. jetError = JET_errInvalidParameter;
  146. goto cleanup;
  147. }
  148. count++;
  149. }
  150. // pTlsJbTableIndex->cbKey = count;
  151. }
  152. else
  153. {
  154. count = pTlsJbTableIndex->cbKey;
  155. }
  156. if(ConvertMWstrToMJBstr(pTlsJbTableIndex->pszIndexKey, count, &pJetIndexCreate->szKey) == FALSE)
  157. {
  158. jetError = JET_errInvalidParameter;
  159. goto cleanup;
  160. }
  161. pJetIndexCreate->cbKey = pTlsJbTableIndex->cbKey;
  162. pJetIndexCreate->grbit = pTlsJbTableIndex->jbGrbit;
  163. pJetIndexCreate->ulDensity = pTlsJbTableIndex->ulDensity;
  164. cleanup:
  165. return jetError;
  166. }
  167. //////////////////////////////////////////////////////////////////////
  168. //
  169. // JBInstance implementaion
  170. //
  171. //////////////////////////////////////////////////////////////////////
  172. JBInstance::JBInstance() :
  173. JBError(),
  174. m_JetInstance(0),
  175. m_bInit(FALSE),
  176. m_NumSession(0)
  177. {
  178. }
  179. //--------------------------------------------------------------------
  180. JBInstance::~JBInstance()
  181. {
  182. if(m_bInit == FALSE)
  183. {
  184. return;
  185. }
  186. //JB_ASSERT(m_NumSession == 0);
  187. //if(m_NumSession != 0)
  188. //{
  189. // throw JBError(JET_errTooManyActiveUsers);
  190. //}
  191. JBTerminate();
  192. }
  193. //--------------------------------------------------------------------
  194. BOOL
  195. JBInstance::JBInitJetInstance()
  196. {
  197. char szLogFilePath[MAX_PATH+1];
  198. LPTSTR pszLogPath=NULL;
  199. BOOL bSuccess;
  200. if(m_bInit == TRUE)
  201. {
  202. SetLastJetError(JET_errAlreadyInitialized);
  203. return FALSE;
  204. }
  205. SINGLE_JET_CALL;
  206. m_JetErr = JetInit(&m_JetInstance);
  207. if(m_JetErr == JET_errMissingLogFile)
  208. {
  209. //
  210. // Delete log file and retry operation again
  211. //
  212. bSuccess = GetSystemParameter(
  213. 0,
  214. JET_paramLogFilePath,
  215. NULL,
  216. (PBYTE)szLogFilePath,
  217. sizeof(szLogFilePath)
  218. );
  219. if(bSuccess == TRUE && ConvertJBstrToWstr(szLogFilePath, &pszLogPath))
  220. {
  221. DeleteFilesInDirectory(
  222. pszLogPath,
  223. JETBLUE_RESLOG,
  224. FALSE
  225. );
  226. DeleteFilesInDirectory(
  227. pszLogPath,
  228. JETBLUE_EDBLOG,
  229. FALSE
  230. );
  231. m_JetErr = JetInit(&m_JetInstance);
  232. }
  233. }
  234. m_bInit = IsSuccess();
  235. return m_bInit;
  236. }
  237. //--------------------------------------------------------------------
  238. BOOL
  239. JBInstance::JBTerminate(
  240. IN JET_GRBIT grbit,
  241. IN BOOL bDeleteLogFile
  242. )
  243. {
  244. char szLogFilePath[MAX_PATH+1];
  245. LPTSTR pszLogPath=NULL;
  246. BOOL bSuccess;
  247. if(m_bInit == FALSE)
  248. return TRUE;
  249. //
  250. // LSTESTER bug - one thread was still in enumeration while
  251. // the other thread shutdown server
  252. //
  253. //if(m_NumSession > 0)
  254. //{
  255. // JB_ASSERT(m_NumSession == 0);
  256. // SetLastJetError(JET_errTooManyActiveUsers);
  257. // return FALSE;
  258. //}
  259. SINGLE_JET_CALL;
  260. m_JetErr = JetTerm2(m_JetInstance, grbit);
  261. // JB_ASSERT(m_JetErr == JET_errSuccess);
  262. if(m_JetErr == JET_errSuccess && bDeleteLogFile == TRUE)
  263. {
  264. //
  265. // Delete log file.
  266. //
  267. bSuccess = GetSystemParameter(
  268. 0,
  269. JET_paramLogFilePath,
  270. NULL,
  271. (PBYTE)szLogFilePath,
  272. sizeof(szLogFilePath)
  273. );
  274. if(bSuccess == TRUE && ConvertJBstrToWstr(szLogFilePath, &pszLogPath))
  275. {
  276. DeleteFilesInDirectory(
  277. pszLogPath,
  278. JETBLUE_RESLOG,
  279. FALSE
  280. );
  281. DeleteFilesInDirectory(
  282. pszLogPath,
  283. JETBLUE_EDBLOG,
  284. FALSE
  285. );
  286. }
  287. }
  288. m_bInit = FALSE;
  289. // need to add operator= to this class.
  290. // m_NumSession = 0; // force terminate.
  291. if(pszLogPath != NULL)
  292. {
  293. LocalFree(pszLogPath);
  294. }
  295. return (m_JetErr == JET_errSuccess);
  296. }
  297. //--------------------------------------------------------------------
  298. BOOL
  299. JBInstance::SetSystemParameter(
  300. IN JET_SESID SesId,
  301. IN unsigned long lParamId,
  302. IN ULONG_PTR lParam,
  303. IN PBYTE sz
  304. )
  305. {
  306. LPSTR lpszParm=NULL;
  307. if(lParamId == JET_paramSystemPath ||
  308. lParamId == JET_paramTempPath ||
  309. lParamId == JET_paramLogFilePath )
  310. {
  311. if(ConvertWstrToJBstr((LPTSTR)sz, &lpszParm) == FALSE)
  312. {
  313. SetLastJetError(JET_errInvalidParameter);
  314. return FALSE;
  315. }
  316. }
  317. else
  318. {
  319. lpszParm = (LPSTR)sz;
  320. }
  321. SINGLE_JET_CALL;
  322. m_JetErr = JetSetSystemParameter(
  323. &m_JetInstance,
  324. SesId,
  325. lParamId,
  326. lParam,
  327. (const char *)lpszParm
  328. );
  329. if(lParamId == JET_paramSystemPath || lParamId == JET_paramTempPath ||
  330. lParamId == JET_paramLogFilePath )
  331. {
  332. FreeJBstr(lpszParm);
  333. }
  334. return IsSuccess();
  335. }
  336. //--------------------------------------------------------------------
  337. BOOL
  338. JBInstance::GetSystemParameter(
  339. IN JET_SESID SesId,
  340. IN unsigned long lParamId,
  341. IN ULONG_PTR* plParam,
  342. IN PBYTE sz,
  343. IN unsigned long cbMax
  344. )
  345. {
  346. SINGLE_JET_CALL;
  347. m_JetErr = JetGetSystemParameter(
  348. m_JetInstance,
  349. SesId,
  350. lParamId,
  351. plParam,
  352. (char *)sz,
  353. cbMax
  354. );
  355. return IsSuccess();
  356. }
  357. //--------------------------------------------------------------------
  358. CLASS_PRIVATE JET_SESID
  359. JBInstance::BeginJetSession(
  360. IN LPCTSTR pszUserName,
  361. IN LPCTSTR pszPwd
  362. )
  363. {
  364. JET_SESID sesId = JET_sesidNil;
  365. LPSTR lpszUserName=NULL;
  366. LPSTR lpszPwd=NULL;
  367. if(m_bInit == FALSE)
  368. {
  369. SetLastJetError(JET_errNotInitialized);
  370. return JET_sesidNil;
  371. }
  372. if(ConvertWstrToJBstr(pszUserName, &lpszUserName) == FALSE)
  373. {
  374. SetLastJetError(JET_errInvalidParameter);
  375. goto cleanup;
  376. }
  377. if(ConvertWstrToJBstr(pszPwd, &lpszPwd) == FALSE)
  378. {
  379. SetLastJetError(JET_errInvalidParameter);
  380. goto cleanup;
  381. }
  382. {
  383. SINGLE_JET_CALL;
  384. m_JetErr = JetBeginSession(
  385. m_JetInstance,
  386. &sesId,
  387. lpszUserName,
  388. lpszPwd
  389. );
  390. }
  391. if(IsSuccess() == TRUE)
  392. {
  393. m_NumSession++;
  394. }
  395. cleanup:
  396. FreeJBstr(lpszUserName);
  397. FreeJBstr(lpszPwd);
  398. return IsSuccess() ? sesId : JET_sesidNil;
  399. }
  400. //--------------------------------------------------------------------
  401. CLASS_PRIVATE BOOL
  402. JBInstance::EndJetSession(
  403. IN JET_SESID JetSessionID,
  404. IN JET_GRBIT grbit
  405. )
  406. {
  407. SINGLE_JET_CALL;
  408. m_JetErr = JetEndSession(JetSessionID, grbit);
  409. if(IsSuccess() == TRUE)
  410. {
  411. m_NumSession--;
  412. }
  413. return IsSuccess();
  414. }
  415. //--------------------------------------------------------------------
  416. CLASS_PRIVATE BOOL
  417. JBInstance::EndSession(
  418. IN JET_SESID sesId,
  419. IN JET_GRBIT grbit
  420. )
  421. {
  422. return EndJetSession( sesId, grbit );
  423. }
  424. //----------------------------------------------------------------------------
  425. // Implementation for JBSession
  426. //----------------------------------------------------------------------------
  427. JBSession::JBSession(
  428. IN JBInstance& JetInstance,
  429. IN JET_SESID JetSessID
  430. ) :
  431. JBError(),
  432. m_JetInstance(JetInstance),
  433. m_JetSessionID(JetSessID),
  434. m_TransactionLevel(0),
  435. m_JetDBInitialized(0)
  436. /*
  437. */
  438. {
  439. }
  440. //-----------------------------------------------------------
  441. JBSession::JBSession(
  442. IN JBSession& JetSession
  443. ) :
  444. JBError(),
  445. m_JetInstance(JetSession.GetJetInstance()),
  446. m_JetSessionID(JET_sesidNil),
  447. m_TransactionLevel(0),
  448. m_JetDBInitialized(0)
  449. {
  450. if(DuplicateSession(JetSession.GetJetSessionID()) == FALSE)
  451. {
  452. JB_ASSERT(FALSE);
  453. throw JBError(GetLastJetError());
  454. }
  455. }
  456. //-----------------------------------------------------------
  457. JBSession::~JBSession()
  458. /*
  459. */
  460. {
  461. if(IsValid() == TRUE && EndSession() == FALSE)
  462. {
  463. // do nothing, license server uses only global instance
  464. // JB_ASSERT(FALSE);
  465. // throw JBError(GetLastJetError());
  466. }
  467. }
  468. //----------------------------------------------------------
  469. CLASS_PRIVATE BOOL
  470. JBSession::DuplicateSession(
  471. IN JET_SESID sessID
  472. )
  473. {
  474. SINGLE_JET_CALL;
  475. m_JetErr = JetDupSession(sessID, &m_JetSessionID);
  476. return IsSuccess();
  477. }
  478. //----------------------------------------------------------
  479. CLASS_PRIVATE JET_DBID
  480. JBSession::OpenJetDatabase(
  481. IN LPCTSTR pszFile,
  482. IN LPCTSTR pszConnect,
  483. IN JET_GRBIT grbit
  484. )
  485. {
  486. JET_DBID jdbId = JET_dbidNil;
  487. LPSTR lpszFile=NULL;
  488. LPSTR lpszConnect=NULL;
  489. if(ConvertWstrToJBstr(pszFile, &lpszFile) == FALSE)
  490. {
  491. SetLastJetError(JET_errInvalidParameter);
  492. goto cleanup;
  493. }
  494. if(ConvertWstrToJBstr(pszConnect, &lpszConnect) == FALSE)
  495. {
  496. SetLastJetError(JET_errInvalidParameter);
  497. goto cleanup;
  498. }
  499. if(AttachDatabase(pszFile, grbit) == FALSE)
  500. goto cleanup;
  501. {
  502. SINGLE_JET_CALL;
  503. m_JetErr = JetOpenDatabase(
  504. m_JetSessionID,
  505. lpszFile,
  506. lpszConnect,
  507. &jdbId,
  508. grbit
  509. );
  510. }
  511. if(IsSuccess() == TRUE)
  512. {
  513. m_JetDBInitialized++;
  514. }
  515. cleanup:
  516. FreeJBstr(lpszFile);
  517. FreeJBstr(lpszConnect);
  518. return IsSuccess() ? jdbId : JET_dbidNil;
  519. }
  520. //----------------------------------------------------------
  521. CLASS_PRIVATE BOOL
  522. JBSession::CloseJetDatabase(
  523. IN JET_DBID jdbId,
  524. IN JET_GRBIT grbit
  525. )
  526. {
  527. SINGLE_JET_CALL;
  528. m_JetErr = JetCloseDatabase(
  529. m_JetSessionID,
  530. jdbId,
  531. grbit
  532. );
  533. if(IsSuccess() == TRUE)
  534. {
  535. m_JetDBInitialized--;
  536. }
  537. return (IsSuccess());
  538. }
  539. //----------------------------------------------------------
  540. CLASS_PRIVATE JET_DBID
  541. JBSession::CreateJetDatabase(
  542. IN LPCTSTR pszFile,
  543. IN LPCTSTR pszConnect,
  544. IN JET_GRBIT grbit
  545. )
  546. {
  547. JET_DBID jdbId = JET_dbidNil;
  548. LPSTR lpszFile=NULL;
  549. LPSTR lpszConnect=NULL;
  550. if(ConvertWstrToJBstr(pszFile, &lpszFile) == FALSE)
  551. {
  552. SetLastError(JET_errInvalidParameter);
  553. goto cleanup;
  554. }
  555. if(ConvertWstrToJBstr(pszConnect, &lpszConnect) == FALSE)
  556. {
  557. SetLastError(JET_errInvalidParameter);
  558. goto cleanup;
  559. }
  560. {
  561. SINGLE_JET_CALL;
  562. m_JetErr = JetCreateDatabase(
  563. m_JetSessionID,
  564. lpszFile,
  565. lpszConnect,
  566. &jdbId,
  567. grbit
  568. );
  569. }
  570. if(IsSuccess() == TRUE)
  571. {
  572. m_JetDBInitialized++;
  573. }
  574. cleanup:
  575. FreeJBstr(lpszFile);
  576. FreeJBstr(lpszConnect);
  577. return IsSuccess() ? jdbId : JET_dbidNil;
  578. }
  579. //----------------------------------------------------------
  580. BOOL
  581. JBSession::BeginSession(
  582. IN LPCTSTR pszUserName,
  583. IN LPCTSTR pszPwd
  584. )
  585. /*
  586. */
  587. {
  588. BOOL bSuccess;
  589. if(m_JetInstance.IsValid() == FALSE)
  590. {
  591. SetLastJetError(JET_errNotInitialized);
  592. return FALSE;
  593. }
  594. if(m_JetSessionID != JET_sesidNil)
  595. {
  596. SetLastJetError(JET_errAlreadyInitialized);
  597. return FALSE;
  598. }
  599. m_JetSessionID = m_JetInstance.BeginJetSession(
  600. pszUserName,
  601. pszPwd
  602. );
  603. if(m_JetSessionID == JET_sesidNil)
  604. {
  605. m_JetErr = m_JetInstance.GetLastJetError();
  606. }
  607. return IsSuccess();
  608. }
  609. //----------------------------------------------------------
  610. BOOL
  611. JBSession::EndSession(
  612. IN JET_GRBIT grbit /* JET_bitTermComplete */
  613. )
  614. /*
  615. */
  616. {
  617. BOOL bSuccess;
  618. if(GetTransactionLevel() != 0)
  619. {
  620. //
  621. // Terminate existing transaction
  622. //
  623. bSuccess = EndAllTransaction(FALSE);
  624. if(bSuccess == FALSE)
  625. {
  626. JB_ASSERT(FALSE);
  627. SetLastJetError(JET_errTransTooDeep);
  628. return FALSE;
  629. }
  630. }
  631. if(IsValid() == FALSE)
  632. {
  633. SetLastJetError(JET_errNotInitialized);
  634. return FALSE;
  635. }
  636. if(m_JetDBInitialized > 0)
  637. {
  638. JB_ASSERT(m_JetDBInitialized);
  639. SetLastJetError(JET_errTooManyActiveUsers);
  640. return FALSE;
  641. }
  642. //
  643. // Huei - routine to be phrased out ?
  644. //
  645. bSuccess=m_JetInstance.EndSession(
  646. m_JetSessionID,
  647. grbit
  648. );
  649. if(bSuccess == TRUE)
  650. {
  651. m_JetSessionID = JET_sesidNil;
  652. }
  653. else
  654. {
  655. m_JetErr = m_JetInstance.GetLastJetError();
  656. }
  657. return IsSuccess();
  658. }
  659. //------------------------------------------------------------
  660. BOOL
  661. JBSession::SetSystemParameter(
  662. IN unsigned long lParamId,
  663. IN ULONG_PTR lParam,
  664. IN const PBYTE sz
  665. )
  666. {
  667. BOOL bSuccess;
  668. bSuccess = m_JetInstance.SetSystemParameter(
  669. m_JetSessionID,
  670. lParamId,
  671. lParam,
  672. sz
  673. );
  674. if(bSuccess == FALSE)
  675. {
  676. m_JetErr = m_JetInstance.GetLastJetError();
  677. }
  678. return IsSuccess();
  679. }
  680. //--------------------------------------------------------------------
  681. BOOL
  682. JBSession::GetSystemParameter(
  683. IN unsigned long lParamId,
  684. IN ULONG_PTR* plParam,
  685. IN PBYTE sz,
  686. IN unsigned long cbMax
  687. )
  688. {
  689. BOOL bSuccess;
  690. bSuccess = m_JetInstance.GetSystemParameter(
  691. m_JetSessionID,
  692. lParamId,
  693. plParam,
  694. sz,
  695. cbMax
  696. );
  697. if(bSuccess == FALSE)
  698. {
  699. m_JetErr = m_JetInstance.GetLastJetError();
  700. }
  701. return IsSuccess();
  702. }
  703. //--------------------------------------------------------------------
  704. BOOL
  705. JBSession::AttachDatabase(
  706. IN LPCTSTR pszFileName,
  707. IN JET_GRBIT grbit
  708. )
  709. {
  710. LPSTR lpszFileName=NULL;
  711. if(m_JetSessionID == JET_sesidNil)
  712. {
  713. SetLastJetError(JET_errNotInitialized);
  714. goto cleanup;
  715. }
  716. if(ConvertWstrToJBstr(pszFileName, &lpszFileName) == FALSE)
  717. {
  718. SetLastJetError(JET_errInvalidParameter);
  719. goto cleanup;
  720. }
  721. {
  722. SINGLE_JET_CALL;
  723. m_JetErr = JetAttachDatabase(
  724. m_JetSessionID,
  725. lpszFileName,
  726. grbit
  727. );
  728. }
  729. cleanup:
  730. FreeJBstr(lpszFileName);
  731. return IsSuccess();
  732. }
  733. //--------------------------------------------------------------------
  734. BOOL
  735. JBSession::DetachDatabase(
  736. IN LPCTSTR pszFileName
  737. )
  738. {
  739. LPSTR lpszFileName = NULL;
  740. if(m_JetSessionID == JET_sesidNil)
  741. {
  742. SetLastJetError(JET_errNotInitialized);
  743. goto cleanup;
  744. }
  745. if(ConvertWstrToJBstr(pszFileName, &lpszFileName) == FALSE)
  746. {
  747. SetLastJetError(JET_errInvalidParameter);
  748. goto cleanup;
  749. }
  750. {
  751. SINGLE_JET_CALL;
  752. m_JetErr = JetDetachDatabase(
  753. m_JetSessionID,
  754. lpszFileName
  755. );
  756. }
  757. cleanup:
  758. FreeJBstr(lpszFileName);
  759. return IsSuccess();
  760. }
  761. //--------------------------------------------------------------------
  762. BOOL
  763. JBSession::BeginTransaction()
  764. {
  765. if(m_JetSessionID == JET_sesidNil)
  766. {
  767. SetLastJetError(JET_errNotInitialized);
  768. return FALSE;
  769. }
  770. SINGLE_JET_CALL;
  771. m_JetErr = JetBeginTransaction(
  772. m_JetSessionID
  773. );
  774. if(IsSuccess() == TRUE)
  775. {
  776. m_TransactionLevel++;
  777. }
  778. return IsSuccess();
  779. }
  780. //--------------------------------------------------------------------
  781. BOOL
  782. JBSession::CommitTransaction(
  783. IN JET_GRBIT grbit
  784. )
  785. {
  786. if(m_JetSessionID == JET_sesidNil)
  787. {
  788. SetLastJetError(JET_errNotInitialized);
  789. return FALSE;
  790. }
  791. SINGLE_JET_CALL;
  792. m_JetErr = JetCommitTransaction(
  793. m_JetSessionID,
  794. grbit
  795. );
  796. if(IsSuccess() == TRUE)
  797. {
  798. m_TransactionLevel --;
  799. }
  800. return IsSuccess();
  801. }
  802. //--------------------------------------------------------------------
  803. BOOL
  804. JBSession::RollbackTransaction(
  805. IN JET_GRBIT grbit
  806. )
  807. {
  808. if(m_JetSessionID == JET_sesidNil)
  809. {
  810. SetLastJetError(JET_errNotInitialized);
  811. return FALSE;
  812. }
  813. SINGLE_JET_CALL;
  814. m_JetErr = JetRollback(
  815. m_JetSessionID,
  816. grbit
  817. );
  818. if(IsSuccess() == TRUE)
  819. m_TransactionLevel--;
  820. return IsSuccess();
  821. }
  822. //--------------------------------------------------------------------
  823. BOOL
  824. JBSession::EndAllTransaction(
  825. IN BOOL bCommit,
  826. IN JET_GRBIT grbit
  827. )
  828. {
  829. BOOL bEnd = TRUE;
  830. while(m_TransactionLevel > 0 && bEnd == TRUE)
  831. {
  832. bEnd = (bCommit == TRUE) ?
  833. CommitTransaction(grbit) : RollbackTransaction(grbit);
  834. }
  835. return bEnd;
  836. }
  837. //--------------------------------------------------------------------
  838. CLASS_PRIVATE BOOL
  839. JBSession::CloseDatabase(
  840. JET_DBID jdbId,
  841. JET_GRBIT grbit
  842. )
  843. {
  844. return CloseJetDatabase(jdbId, grbit);
  845. }
  846. //////////////////////////////////////////////////////////////////////
  847. //
  848. // JBDatabase
  849. //
  850. //////////////////////////////////////////////////////////////////////
  851. JBDatabase::JBDatabase(
  852. IN JBSession& jbSession,
  853. IN JET_DBID jdbId, /* JET_dbidNil */
  854. IN LPCTSTR pszDatabase // NULL
  855. ) :
  856. JBError(),
  857. m_JetSession(jbSession),
  858. m_JetDbId(jdbId),
  859. m_TableOpened(0)
  860. /*
  861. */
  862. {
  863. if(pszDatabase)
  864. {
  865. _tcscpy(m_szDatabaseFile, pszDatabase);
  866. }
  867. else
  868. {
  869. memset(m_szDatabaseFile, 0, sizeof(m_szDatabaseFile));
  870. }
  871. }
  872. //--------------------------------------------------------------------
  873. JBDatabase::~JBDatabase()
  874. {
  875. if(CloseDatabase() == FALSE)
  876. {
  877. // do nothing, license server uses only global instance.
  878. // JB_ASSERT(FALSE);
  879. // throw JBError(GetLastJetError());
  880. }
  881. }
  882. //--------------------------------------------------------------------
  883. BOOL
  884. JBDatabase::CloseDatabase(
  885. IN JET_GRBIT grbit
  886. )
  887. {
  888. BOOL bSuccess;
  889. //
  890. // Verify we have properly initialized
  891. //
  892. if(IsValid() == FALSE)
  893. return TRUE;
  894. //
  895. // No table is still opened from the DB ID
  896. //
  897. if(m_TableOpened > 0)
  898. {
  899. JB_ASSERT(FALSE);
  900. SetLastJetError(JET_errTooManyActiveUsers);
  901. return FALSE;
  902. }
  903. //
  904. // Close the database
  905. //
  906. bSuccess = m_JetSession.CloseJetDatabase(
  907. m_JetDbId,
  908. grbit
  909. );
  910. if(bSuccess == FALSE || m_JetSession.DetachDatabase(m_szDatabaseFile) == FALSE)
  911. {
  912. m_JetErr = m_JetSession.GetLastJetError();
  913. }
  914. else
  915. {
  916. m_JetDbId = JET_dbidNil;
  917. memset(m_szDatabaseFile, 0, sizeof(m_szDatabaseFile));
  918. }
  919. return IsSuccess();
  920. }
  921. //--------------------------------------------------------------------
  922. CLASS_PRIVATE JET_TABLEID
  923. JBDatabase::OpenJetTable(
  924. IN LPCTSTR pszTableName,
  925. IN void* pvParam, // NULL
  926. IN unsigned long cbParam, // 0
  927. JET_GRBIT grbit // JET_bitTableUpdatable
  928. )
  929. /*
  930. */
  931. {
  932. LPSTR lpszTableName = NULL;
  933. JET_TABLEID tableid = JET_tableidNil;
  934. if(IsValid() == FALSE)
  935. {
  936. SetLastJetError(JET_errInvalidDatabaseId);
  937. goto cleanup;
  938. }
  939. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  940. {
  941. SetLastJetError(JET_errInvalidParameter);
  942. goto cleanup;
  943. }
  944. {
  945. SINGLE_JET_CALL;
  946. m_JetErr=JetOpenTable(
  947. m_JetSession.GetJetSessionID(),
  948. m_JetDbId,
  949. lpszTableName,
  950. pvParam,
  951. cbParam,
  952. grbit,
  953. &tableid
  954. );
  955. }
  956. if(IsSuccess() == TRUE)
  957. {
  958. m_TableOpened++;
  959. }
  960. cleanup:
  961. FreeJBstr(lpszTableName);
  962. return tableid;
  963. }
  964. //--------------------------------------------------------------------
  965. CLASS_PRIVATE JET_TABLEID
  966. JBDatabase::DuplicateJetCursor(
  967. // IN JET_SESID sesId,
  968. IN JET_TABLEID srcTableid,
  969. IN JET_GRBIT grbit
  970. )
  971. /*
  972. */
  973. {
  974. JET_TABLEID tableid = JET_tableidNil;
  975. SINGLE_JET_CALL;
  976. m_JetErr = JetDupCursor(
  977. GetJetSessionID(),
  978. srcTableid,
  979. &tableid,
  980. 0 // grbit must be zero
  981. );
  982. if(IsSuccess() == TRUE)
  983. {
  984. m_TableOpened++;
  985. }
  986. return (IsSuccess() == TRUE) ? tableid : JET_tableidNil;
  987. }
  988. //--------------------------------------------------------------------
  989. CLASS_PRIVATE BOOL
  990. JBDatabase::CloseJetTable(
  991. // IN JET_SESID sesId,
  992. IN JET_TABLEID tableid
  993. )
  994. /*
  995. */
  996. {
  997. // JetBlue AC with empty table
  998. SINGLE_JET_CALL;
  999. try {
  1000. m_JetErr = JetCloseTable(
  1001. GetJetSessionID(),
  1002. tableid
  1003. );
  1004. }
  1005. catch(...) {
  1006. m_JetErr = JET_errSuccess;
  1007. }
  1008. if(IsSuccess())
  1009. {
  1010. m_TableOpened--;
  1011. }
  1012. return IsSuccess();
  1013. }
  1014. //--------------------------------------------------------------------
  1015. CLASS_PRIVATE JET_TABLEID
  1016. JBDatabase::CreateJetTable(
  1017. LPCTSTR pszTableName,
  1018. unsigned long lPage, // 0
  1019. unsigned long lDensity // 20
  1020. )
  1021. /*
  1022. */
  1023. {
  1024. JET_TABLEID tableid = JET_tableidNil;
  1025. JB_STRING lpszTableName=NULL;
  1026. if(IsValid() == FALSE)
  1027. {
  1028. SetLastJetError(JET_errNotInitialized);
  1029. goto cleanup;
  1030. }
  1031. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  1032. {
  1033. SetLastJetError(JET_errInvalidParameter);
  1034. goto cleanup;
  1035. }
  1036. {
  1037. SINGLE_JET_CALL;
  1038. m_JetErr = JetCreateTable(
  1039. GetJetSessionID(),
  1040. m_JetDbId,
  1041. lpszTableName,
  1042. lPage,
  1043. lDensity,
  1044. &tableid
  1045. );
  1046. }
  1047. if(IsSuccess() == FALSE)
  1048. {
  1049. goto cleanup;
  1050. }
  1051. m_TableOpened++;
  1052. cleanup:
  1053. FreeJBstr(lpszTableName);
  1054. return tableid;
  1055. }
  1056. //--------------------------------------------------------------------
  1057. CLASS_PRIVATE JET_TABLEID
  1058. JBDatabase::CreateJetTableEx(
  1059. LPCTSTR pszTableName,
  1060. const PTLSJBTable table_attribute,
  1061. const PTLSJBColumn columns,
  1062. const DWORD num_columns,
  1063. const PTLSJBIndex table_index,
  1064. const DWORD num_table_index
  1065. )
  1066. /*
  1067. */
  1068. {
  1069. JET_TABLEID tableid = JET_tableidNil;
  1070. JB_STRING lpszTableName=NULL;
  1071. JET_TABLECREATE table_create;
  1072. JET_COLUMNCREATE* column_create=NULL;
  1073. JET_INDEXCREATE* index_create=NULL;
  1074. DWORD index=0;
  1075. SINGLE_JET_CALL;
  1076. table_create.szTableName = NULL;
  1077. table_create.szTemplateTableName = NULL;
  1078. if(IsValid() == FALSE)
  1079. {
  1080. SetLastJetError(JET_errNotInitialized);
  1081. goto cleanup;
  1082. }
  1083. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  1084. {
  1085. SetLastJetError(JET_errInvalidParameter);
  1086. goto cleanup;
  1087. }
  1088. table_create.cbStruct = sizeof(JET_TABLECREATE);
  1089. table_create.szTableName = lpszTableName;
  1090. if(ConvertWstrToJBstr(table_attribute->pszTemplateTableName, &table_create.szTemplateTableName) == FALSE)
  1091. {
  1092. SetLastJetError(JET_errInvalidParameter);
  1093. goto cleanup;
  1094. }
  1095. table_create.ulPages = table_attribute->ulPages;
  1096. table_create.ulDensity = (table_attribute->ulDensity < 20 || table_attribute->ulDensity > 100) ?
  1097. TLS_JETBLUE_DEFAULT_TABLE_DENSITY : table_attribute->ulDensity;
  1098. table_create.grbit = table_attribute->jbGrbit;
  1099. //
  1100. // form a JET_TABLECREATE structure
  1101. //
  1102. column_create = (JET_COLUMNCREATE *)AllocateMemory(
  1103. sizeof(JET_COLUMNCREATE) * num_columns
  1104. );
  1105. if(column_create == NULL)
  1106. {
  1107. SetLastJetError(JET_errOutOfMemory);
  1108. goto cleanup;
  1109. }
  1110. index_create = (JET_INDEXCREATE *)AllocateMemory(
  1111. sizeof(JET_INDEXCREATE) * num_table_index
  1112. );
  1113. if(index_create == NULL)
  1114. {
  1115. SetLastJetError(JET_errOutOfMemory);
  1116. goto cleanup;
  1117. }
  1118. for(index=0; index < num_columns; index++)
  1119. {
  1120. if(ConvertTLSJbColumnDefToJbColumnCreate( columns+index, column_create+index ) == FALSE)
  1121. {
  1122. goto cleanup;
  1123. }
  1124. }
  1125. for(index=0; index < num_table_index; index++)
  1126. {
  1127. if(ConvertTlsJBTableIndexDefToJbIndexCreate( table_index+index, index_create+index ) == FALSE)
  1128. goto cleanup;
  1129. }
  1130. table_create.rgcolumncreate = column_create;
  1131. table_create.cColumns = num_columns;
  1132. table_create.rgindexcreate = index_create;
  1133. table_create.cIndexes = num_table_index;
  1134. m_JetErr = JetCreateTableColumnIndex(
  1135. GetJetSessionID(),
  1136. GetJetDatabaseID(),
  1137. &table_create
  1138. );
  1139. if(IsSuccess() == TRUE)
  1140. {
  1141. tableid = table_create.tableid;
  1142. }
  1143. cleanup:
  1144. if(column_create != NULL)
  1145. {
  1146. for(index=0; index < num_columns; index++)
  1147. {
  1148. if(column_create[index].szColumnName != NULL)
  1149. {
  1150. FreeJBstr(column_create[index].szColumnName);
  1151. }
  1152. }
  1153. FreeMemory(column_create);
  1154. }
  1155. if(index_create != NULL)
  1156. {
  1157. for(index=0; index < num_table_index; index++)
  1158. {
  1159. if(index_create[index].szIndexName != NULL)
  1160. {
  1161. FreeJBstr(index_create[index].szIndexName);
  1162. }
  1163. if(index_create[index].szKey != NULL)
  1164. {
  1165. FreeJBstr(index_create[index].szKey);
  1166. }
  1167. }
  1168. FreeMemory(index_create);
  1169. }
  1170. if(table_create.szTemplateTableName)
  1171. FreeJBstr(table_create.szTemplateTableName);
  1172. if(table_create.szTableName)
  1173. FreeJBstr(table_create.szTableName);
  1174. return tableid;
  1175. }
  1176. //--------------------------------------------------------------------
  1177. JET_TABLEID
  1178. JBDatabase::CreateTable(
  1179. LPCTSTR pszTableName,
  1180. unsigned long lPage, // 0
  1181. unsigned long lDensity // 20
  1182. )
  1183. /*
  1184. */
  1185. {
  1186. JET_TABLEID tableid;
  1187. tableid = CreateJetTable(
  1188. pszTableName,
  1189. lPage,
  1190. lDensity
  1191. );
  1192. if(tableid == JET_tableidNil)
  1193. {
  1194. m_JetErr = GetLastJetError();
  1195. }
  1196. return tableid;
  1197. }
  1198. //-------------------------------------------------------------------
  1199. JET_TABLEID
  1200. JBDatabase::CreateTableEx(
  1201. LPCTSTR pszTableName,
  1202. const PTLSJBTable table_attribute,
  1203. const PTLSJBColumn columns,
  1204. DWORD num_columns,
  1205. const PTLSJBIndex index,
  1206. DWORD num_index
  1207. )
  1208. /*
  1209. */
  1210. {
  1211. JET_TABLEID tableid;
  1212. tableid = CreateJetTableEx(
  1213. pszTableName,
  1214. table_attribute,
  1215. columns,
  1216. num_columns,
  1217. index,
  1218. num_index
  1219. );
  1220. if(tableid == JET_tableidNil)
  1221. {
  1222. m_JetErr = GetLastJetError();
  1223. }
  1224. return tableid;
  1225. }
  1226. //--------------------------------------------------------------------
  1227. CLASS_PRIVATE BOOL
  1228. JBDatabase::CloseTable(
  1229. JET_TABLEID tableid
  1230. )
  1231. /*
  1232. ? Verify this table ID is from this DB/Session
  1233. */
  1234. {
  1235. return CloseJetTable( tableid );
  1236. }
  1237. //--------------------------------------------------------------------
  1238. BOOL
  1239. JBDatabase::DeleteTable(
  1240. IN LPCTSTR pszTableName
  1241. )
  1242. /*
  1243. TODO - ? verify this table is in this database
  1244. */
  1245. {
  1246. JB_STRING lpszTableName=NULL;
  1247. if(IsValid() == FALSE)
  1248. {
  1249. SetLastJetError(JET_errNotInitialized);
  1250. goto cleanup;
  1251. }
  1252. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  1253. {
  1254. SetLastJetError(JET_errInvalidParameter);
  1255. goto cleanup;
  1256. }
  1257. {
  1258. SINGLE_JET_CALL;
  1259. m_JetErr = JetDeleteTable(
  1260. GetJetSessionID(),
  1261. GetJetDatabaseID(),
  1262. lpszTableName
  1263. );
  1264. }
  1265. //if(IsSuccess() == FALSE)
  1266. // goto cleanup;
  1267. cleanup:
  1268. FreeJBstr(lpszTableName);
  1269. return IsSuccess();
  1270. }
  1271. //--------------------------------------------------------------------
  1272. BOOL
  1273. JBDatabase::OpenDatabase(
  1274. LPCTSTR szFile,
  1275. LPCTSTR szConnect, // NULL
  1276. JET_GRBIT grbit // 0
  1277. )
  1278. /*
  1279. */
  1280. {
  1281. m_JetDbId = m_JetSession.OpenJetDatabase(
  1282. szFile,
  1283. szConnect,
  1284. grbit
  1285. );
  1286. if(m_JetDbId == JET_dbidNil)
  1287. {
  1288. m_JetErr = m_JetSession.GetLastJetError();
  1289. }
  1290. else
  1291. {
  1292. _tcscpy(m_szDatabaseFile, szFile);
  1293. }
  1294. return m_JetDbId != JET_dbidNil;
  1295. }
  1296. //--------------------------------------------------------------------
  1297. BOOL
  1298. JBDatabase::CreateDatabase(
  1299. LPCTSTR szFile,
  1300. LPCTSTR szConnect, // NULL
  1301. JET_GRBIT grbit // 0
  1302. )
  1303. /*
  1304. */
  1305. {
  1306. m_JetDbId = m_JetSession.CreateJetDatabase(
  1307. szFile,
  1308. szConnect,
  1309. grbit
  1310. );
  1311. if(m_JetDbId == JET_dbidNil)
  1312. {
  1313. m_JetErr = m_JetSession.GetLastJetError();
  1314. }
  1315. else
  1316. {
  1317. _tcscpy(m_szDatabaseFile, szFile);
  1318. }
  1319. return m_JetDbId != JET_dbidNil;
  1320. }
  1321. //////////////////////////////////////////////////////////////////////
  1322. //
  1323. // JBTable
  1324. //
  1325. //////////////////////////////////////////////////////////////////////
  1326. JBColumn JBTable::m_ErrColumn;
  1327. JBTable::JBTable(
  1328. JBDatabase& JetDatabase,
  1329. LPCTSTR pszTableName,
  1330. JET_TABLEID tableid
  1331. ) :
  1332. JBError(),
  1333. m_JetDatabase(JetDatabase),
  1334. m_JetTableId(tableid),
  1335. m_JetColumns(NULL),
  1336. m_NumJetColumns(0),
  1337. m_InEnumeration(FALSE),
  1338. m_InsertRepositionBookmark(FALSE)
  1339. /*
  1340. */
  1341. {
  1342. if(pszTableName)
  1343. {
  1344. _tcscpy(m_szTableName, pszTableName);
  1345. }
  1346. else
  1347. {
  1348. memset(m_szTableName, 0, sizeof(m_szTableName));
  1349. }
  1350. }
  1351. //--------------------------------------------------------------------
  1352. JBTable::JBTable(
  1353. JBTable& jbTable
  1354. ) :
  1355. JBError(),
  1356. m_JetDatabase(jbTable.GetJetDatabase()),
  1357. m_JetColumns(NULL),
  1358. m_NumJetColumns(0),
  1359. m_InEnumeration(FALSE)
  1360. /*
  1361. */
  1362. {
  1363. // duplicate jet cursor
  1364. _tcscpy(m_szTableName, jbTable.GetTableName());
  1365. m_JetTableId = m_JetDatabase.DuplicateJetCursor(
  1366. jbTable.GetJetTableID(),
  1367. 0
  1368. );
  1369. if(m_JetTableId == JET_tableidNil)
  1370. {
  1371. m_JetErr = m_JetDatabase.GetLastJetError();
  1372. }
  1373. }
  1374. //--------------------------------------------------------------------
  1375. JBTable::~JBTable()
  1376. {
  1377. if(m_JetTableId == JET_tableidNil)
  1378. return;
  1379. CloseTable();
  1380. }
  1381. //--------------------------------------------------------------------
  1382. CLASS_PRIVATE JET_COLUMNID
  1383. JBTable::AddJetColumn(
  1384. LPCTSTR pszColumnName,
  1385. const JET_COLUMNDEF* pColumnDef,
  1386. const PVOID pbDefaultValue, // NULL
  1387. const unsigned long cbDefaultValue // 0
  1388. )
  1389. /*
  1390. */
  1391. {
  1392. DebugOutput(
  1393. _TEXT("Adding column %s to table %s, type %d\n"),
  1394. pszColumnName,
  1395. GetTableName(),
  1396. pColumnDef->coltyp
  1397. );
  1398. JB_STRING lpszColumnName=NULL;
  1399. JET_COLUMNID columnid = (DWORD)JET_NIL_COLUMN;
  1400. if(IsValid() == FALSE)
  1401. {
  1402. SetLastJetError(JET_errInvalidDatabaseId);
  1403. goto cleanup;
  1404. }
  1405. if(ConvertWstrToJBstr(pszColumnName, &lpszColumnName) == FALSE)
  1406. {
  1407. SetLastJetError(JET_errInvalidDatabaseId);
  1408. goto cleanup;
  1409. }
  1410. {
  1411. SINGLE_JET_CALL;
  1412. m_JetErr = JetAddColumn(
  1413. GetJetSessionID(),
  1414. GetJetTableID(),
  1415. lpszColumnName,
  1416. pColumnDef,
  1417. pbDefaultValue,
  1418. cbDefaultValue,
  1419. &columnid
  1420. );
  1421. }
  1422. cleanup:
  1423. DebugOutput(
  1424. _TEXT("AddJetColumn returns %d\n"),
  1425. GetLastJetError()
  1426. );
  1427. FreeJBstr(lpszColumnName);
  1428. return columnid;
  1429. }
  1430. //--------------------------------------------------------------------
  1431. BOOL
  1432. JBTable::AddIndex(
  1433. JBKeyBase* key
  1434. )
  1435. /*
  1436. */
  1437. {
  1438. return AddJetIndex(
  1439. key->GetIndexName(),
  1440. key->GetIndexKey(),
  1441. key->GetKeyLength(),
  1442. key->GetJetGrbit(),
  1443. key->GetJetDensity()
  1444. );
  1445. }
  1446. //--------------------------------------------------------------------
  1447. BOOL
  1448. JBTable::AddJetIndex(
  1449. LPCTSTR pszIndexName,
  1450. LPCTSTR pszKey,
  1451. unsigned long cbKey,
  1452. JET_GRBIT grbit, /* 0 */
  1453. unsigned long lDensity /* 20 */
  1454. )
  1455. /*
  1456. */
  1457. {
  1458. DebugOutput(
  1459. _TEXT("Adding Index %s to table %s\n"),
  1460. pszIndexName,
  1461. GetTableName()
  1462. );
  1463. JB_STRING lpszIndexName=NULL;
  1464. JB_STRING lpszKeyName=NULL;
  1465. if(IsValid() == FALSE)
  1466. {
  1467. SetLastJetError(JET_errInvalidDatabaseId);
  1468. goto cleanup;
  1469. }
  1470. if(ConvertWstrToJBstr(pszIndexName, &lpszIndexName) == FALSE)
  1471. {
  1472. SetLastJetError(JET_errInvalidDatabaseId);
  1473. goto cleanup;
  1474. }
  1475. if(ConvertMWstrToMJBstr(pszKey, cbKey, &lpszKeyName) == FALSE)
  1476. {
  1477. SetLastJetError(JET_errInvalidDatabaseId);
  1478. goto cleanup;
  1479. }
  1480. {
  1481. SINGLE_JET_CALL;
  1482. m_JetErr = JetCreateIndex(
  1483. GetJetSessionID(),
  1484. GetJetTableID(),
  1485. lpszIndexName,
  1486. grbit,
  1487. lpszKeyName,
  1488. cbKey,
  1489. lDensity
  1490. );
  1491. }
  1492. cleanup:
  1493. DebugOutput(
  1494. _TEXT("Adding index %s returns %d\n"),
  1495. pszIndexName,
  1496. GetLastJetError()
  1497. );
  1498. FreeJBstr(lpszIndexName);
  1499. FreeJBstr(lpszKeyName);
  1500. return IsSuccess();
  1501. }
  1502. BOOL
  1503. JBTable::DoesIndexExist(
  1504. LPCTSTR pszIndexName
  1505. )
  1506. {
  1507. JB_STRING lpszIndexName=NULL;
  1508. JET_INDEXID idx;
  1509. if(IsValid() == FALSE)
  1510. {
  1511. SetLastJetError(JET_errInvalidDatabaseId);
  1512. goto cleanup;
  1513. }
  1514. if(ConvertWstrToJBstr(pszIndexName, &lpszIndexName) == FALSE)
  1515. {
  1516. SetLastJetError(JET_errInvalidDatabaseId);
  1517. goto cleanup;
  1518. }
  1519. {
  1520. SINGLE_JET_CALL;
  1521. m_JetErr = JetGetTableIndexInfo(
  1522. GetJetSessionID(),
  1523. GetJetTableID(),
  1524. lpszIndexName,
  1525. &idx,
  1526. sizeof(JET_INDEXID),
  1527. JET_IdxInfoIndexId
  1528. );
  1529. // if this succeeds, the index exists
  1530. }
  1531. cleanup:
  1532. FreeJBstr(lpszIndexName);
  1533. return IsSuccess();
  1534. }
  1535. //--------------------------------------------------------------------
  1536. BOOL
  1537. JBTable::CloseTable()
  1538. {
  1539. BOOL bSuccess;
  1540. if(m_JetTableId == JET_tableidNil)
  1541. return TRUE;
  1542. bSuccess = m_JetDatabase.CloseTable(
  1543. m_JetTableId
  1544. );
  1545. if(bSuccess == FALSE)
  1546. {
  1547. m_JetErr = m_JetDatabase.GetLastJetError();
  1548. }
  1549. //
  1550. // Force close on table.
  1551. //
  1552. m_JetTableId = JET_tableidNil;
  1553. if(m_JetColumns)
  1554. delete [] m_JetColumns;
  1555. m_JetColumns = NULL;
  1556. m_NumJetColumns = 0;
  1557. return bSuccess;
  1558. }
  1559. //--------------------------------------------------------------------
  1560. BOOL
  1561. JBTable::CreateOpenTable(
  1562. IN LPCTSTR pszTableName,
  1563. IN unsigned long lPage, // 0
  1564. IN unsigned long lDensity // 20
  1565. )
  1566. /*
  1567. */
  1568. {
  1569. if(m_JetTableId != JET_tableidNil)
  1570. {
  1571. SetLastJetError(JET_errInvalidParameter);
  1572. return FALSE;
  1573. }
  1574. DebugOutput(
  1575. _TEXT("Creating Table %s\n"),
  1576. pszTableName
  1577. );
  1578. m_JetTableId = m_JetDatabase.CreateJetTable(
  1579. pszTableName,
  1580. lPage,
  1581. lDensity
  1582. );
  1583. if(m_JetTableId == JET_tableidNil)
  1584. {
  1585. m_JetErr = m_JetDatabase.GetLastJetError();
  1586. }
  1587. return (m_JetTableId != JET_tableidNil);
  1588. }
  1589. //--------------------------------------------------------------------
  1590. BOOL
  1591. JBTable::OpenTable(
  1592. IN LPCTSTR pszTableName,
  1593. IN void* pvParam,
  1594. IN unsigned long cbParam,
  1595. IN JET_GRBIT grbit
  1596. )
  1597. /*
  1598. */
  1599. {
  1600. DebugOutput(
  1601. _TEXT("Opening table %s\n"),
  1602. pszTableName
  1603. );
  1604. JB_ASSERT(m_JetTableId == JET_tableidNil);
  1605. if(m_JetTableId != JET_tableidNil)
  1606. {
  1607. SetLastJetError(JET_errTableInUse);
  1608. return FALSE;
  1609. }
  1610. m_JetTableId = m_JetDatabase.OpenJetTable(
  1611. pszTableName,
  1612. pvParam,
  1613. cbParam,
  1614. grbit
  1615. );
  1616. if(m_JetTableId == JET_tableidNil)
  1617. {
  1618. m_JetErr = m_JetDatabase.GetLastJetError();
  1619. }
  1620. else
  1621. {
  1622. // load column info in the table
  1623. _tcscpy(m_szTableName, pszTableName);
  1624. if(LoadTableInfo() == FALSE)
  1625. {
  1626. // force a close on table
  1627. CloseTable();
  1628. }
  1629. }
  1630. DebugOutput(
  1631. _TEXT("Open table %s return code %d\n"),
  1632. pszTableName,
  1633. GetLastJetError()
  1634. );
  1635. return (m_JetTableId != JET_tableidNil);
  1636. }
  1637. //--------------------------------------------------------------------
  1638. JBTable*
  1639. JBTable::DuplicateCursor(
  1640. JET_GRBIT grbit /* 0 */
  1641. )
  1642. /*
  1643. */
  1644. {
  1645. JET_TABLEID tableid;
  1646. tableid = m_JetDatabase.DuplicateJetCursor(
  1647. m_JetTableId,
  1648. grbit
  1649. );
  1650. if(tableid == JET_tableidNil)
  1651. {
  1652. m_JetErr = m_JetDatabase.GetLastJetError();
  1653. }
  1654. return new JBTable(
  1655. m_JetDatabase,
  1656. GetTableName(),
  1657. tableid
  1658. );
  1659. }
  1660. //--------------------------------------------------------------------
  1661. JBTable&
  1662. JBTable::operator=(const JBTable& srcTable)
  1663. {
  1664. if(this == &srcTable)
  1665. return *this;
  1666. // database has to be the same
  1667. // verify database is consistent
  1668. _tcscpy(m_szTableName, srcTable.GetTableName());
  1669. m_JetTableId = m_JetDatabase.DuplicateJetCursor(
  1670. srcTable.GetJetTableID(),
  1671. 0
  1672. );
  1673. if(m_JetTableId == JET_tableidNil)
  1674. {
  1675. m_JetErr = m_JetDatabase.GetLastJetError();
  1676. }
  1677. return *this;
  1678. }
  1679. //--------------------------------------------------------------------
  1680. int
  1681. JBTable::AddColumn(
  1682. int numColumns,
  1683. PTLSJBColumn pColumnDef
  1684. )
  1685. /*
  1686. */
  1687. {
  1688. JET_COLUMNDEF column;
  1689. JET_COLUMNID jet_columnid;
  1690. for(int i=0; i < numColumns; i++)
  1691. {
  1692. memset(&column, 0, sizeof(column));
  1693. column.cbStruct = sizeof(JET_COLUMNDEF);
  1694. column.coltyp = (pColumnDef+i)->colType;
  1695. column.wCountry = (pColumnDef+i)->wCountry;
  1696. column.langid = (pColumnDef+i)->langid;
  1697. column.cp = (pColumnDef+i)->colCodePage;
  1698. column.cbMax = (pColumnDef+i)->cbMaxLength;
  1699. column.grbit = (pColumnDef+i)->jbGrbit;
  1700. jet_columnid = AddJetColumn(
  1701. (pColumnDef+i)->pszColumnName,
  1702. &column,
  1703. (pColumnDef+i)->pbDefValue,
  1704. (pColumnDef+i)->cbDefValue
  1705. );
  1706. if(jet_columnid == JET_NIL_COLUMN)
  1707. break;
  1708. }
  1709. // return which column cause trouble
  1710. return i;
  1711. }
  1712. //--------------------------------------------------------------------
  1713. int
  1714. JBTable::AddIndex(
  1715. int numIndex,
  1716. PTLSJBIndex pIndex
  1717. )
  1718. /*
  1719. */
  1720. {
  1721. unsigned long keylength;
  1722. for(int i=0; i < numIndex; i++)
  1723. {
  1724. if((pIndex+i)->cbKey == -1)
  1725. {
  1726. // calculate index key length
  1727. keylength = 2;
  1728. while((pIndex+i)->pszIndexKey[keylength-1] != _TEXT('\0') ||
  1729. (pIndex+i)->pszIndexKey[keylength-2] != _TEXT('\0'))
  1730. {
  1731. if(keylength >= TLS_JETBLUE_MAX_INDEXKEY_LENGTH)
  1732. {
  1733. SetLastJetError(JET_errInvalidParameter);
  1734. break;
  1735. }
  1736. keylength++;
  1737. }
  1738. }
  1739. else
  1740. {
  1741. keylength = (pIndex+i)->cbKey;
  1742. }
  1743. if(keylength >= TLS_JETBLUE_MAX_INDEXKEY_LENGTH)
  1744. {
  1745. SetLastJetError(JET_errInvalidParameter);
  1746. break;
  1747. }
  1748. if(AddJetIndex(
  1749. (pIndex+i)->pszIndexName,
  1750. (pIndex+i)->pszIndexKey,
  1751. keylength,
  1752. (pIndex+i)->jbGrbit,
  1753. (pIndex+i)->ulDensity
  1754. ) == FALSE)
  1755. {
  1756. break;
  1757. }
  1758. }
  1759. return (i >= numIndex) ? 0 : i;
  1760. }
  1761. //-------------------------------------------------------------
  1762. CLASS_PRIVATE BOOL
  1763. JBTable::LoadTableInfo()
  1764. /*
  1765. */
  1766. {
  1767. #if 1
  1768. LPSTR lpszTableName=NULL;
  1769. JET_COLUMNLIST columns;
  1770. unsigned long cbMax;
  1771. JET_RETINFO jetRetInfo;
  1772. char lpszColumnName[MAX_JETBLUE_NAME_LENGTH+1];
  1773. int NumChars;
  1774. unsigned long index;
  1775. SINGLE_JET_CALL;
  1776. if(ConvertWstrToJBstr(GetTableName(), &lpszTableName) == FALSE)
  1777. {
  1778. SetLastJetError(JET_errInvalidParameter);
  1779. goto cleanup;
  1780. }
  1781. memset(&columns, 0, sizeof(columns));
  1782. columns.cbStruct = sizeof(JET_COLUMNLIST);
  1783. cbMax = sizeof(JET_COLUMNLIST);
  1784. m_JetErr = JetGetColumnInfo(
  1785. GetJetSessionID(),
  1786. GetJetDatabaseID(),
  1787. lpszTableName,
  1788. NULL,
  1789. (PVOID)&columns,
  1790. cbMax,
  1791. 1 // retrieve column list
  1792. );
  1793. if(IsSuccess() == FALSE)
  1794. goto cleanup;
  1795. //
  1796. // Table has just been created
  1797. //
  1798. if(columns.cRecord == 0)
  1799. goto cleanup;
  1800. m_JetColumns = new JBColumn[columns.cRecord];
  1801. if(m_JetColumns == NULL)
  1802. {
  1803. SetLastJetError(JET_errOutOfMemory);
  1804. goto cleanup;
  1805. }
  1806. SetLastJetError(JET_errSuccess);
  1807. //
  1808. // TODO - use JBColumn class to retrieve value
  1809. //
  1810. m_NumJetColumns = columns.cRecord;
  1811. for(index=0;
  1812. index < columns.cRecord && IsSuccess() == TRUE;
  1813. index++)
  1814. {
  1815. m_JetColumns[index].AttachToTable(this);
  1816. if(m_JetColumns[index].LoadJetColumnInfoFromJet(&columns) == FALSE)
  1817. {
  1818. m_JetErr = m_JetColumns[index].GetLastJetError();
  1819. break;
  1820. }
  1821. m_JetErr = JetMove(
  1822. GetJetSessionID(),
  1823. columns.tableid,
  1824. JET_MoveNext,
  1825. 0
  1826. );
  1827. }
  1828. if(GetLastJetError() == JET_errNoCurrentRecord && index >= columns.cRecord)
  1829. {
  1830. // otherwise - got to be a JetBlue bug here.
  1831. SetLastJetError(JET_errSuccess);
  1832. }
  1833. //
  1834. //
  1835. //
  1836. cleanup:
  1837. FreeJBstr(lpszTableName);
  1838. if(IsSuccess() == FALSE && m_JetColumns)
  1839. {
  1840. delete [] m_JetColumns;
  1841. m_JetColumns = NULL;
  1842. m_NumJetColumns = 0;
  1843. }
  1844. return IsSuccess();
  1845. #else
  1846. LPSTR lpszTableName=NULL;
  1847. JET_COLUMNLIST columns;
  1848. unsigned long cbMax;
  1849. JET_RETINFO jetRetInfo;
  1850. unsigned long cbActual;
  1851. char lpszColumnName[MAX_JETBLUE_NAME_LENGTH+1];
  1852. int NumChars;
  1853. unsigned long index;
  1854. SINGLE_JET_CALL;
  1855. if(ConvertWstrToJBstr(GetTableName(), &lpszTableName) == FALSE)
  1856. {
  1857. SetLastJetError(JET_errInvalidParameter);
  1858. goto cleanup;
  1859. }
  1860. memset(&columns, 0, sizeof(columns));
  1861. columns.cbStruct = sizeof(JET_COLUMNLIST);
  1862. cbMax = sizeof(JET_COLUMNLIST);
  1863. m_JetErr = JetGetColumnInfo(
  1864. GetJetSessionID(),
  1865. GetJetDatabaseID(),
  1866. lpszTableName,
  1867. NULL,
  1868. (PVOID)&columns,
  1869. cbMax,
  1870. 1 // retrieve column list
  1871. );
  1872. if(IsSuccess() == FALSE)
  1873. goto cleanup;
  1874. //
  1875. // Table has just been created
  1876. //
  1877. if(columns.cRecord == 0)
  1878. goto cleanup;
  1879. // retrieve column name, column id, column type and column size
  1880. m_Columns = (PJetColumns) AllocateMemory(sizeof(JetColumns) * columns.cRecord);
  1881. if(m_Columns == NULL)
  1882. {
  1883. SetLastJetError(JET_errOutOfMemory);
  1884. goto cleanup;
  1885. }
  1886. SetLastJetError(JET_errSuccess);
  1887. //
  1888. // TODO - use JBColumn class to retrieve value
  1889. //
  1890. m_NumColumns = columns.cRecord;
  1891. for(index=0;
  1892. index < columns.cRecord && IsSuccess() == TRUE;
  1893. index++)
  1894. {
  1895. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1896. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1897. // retrieve column name
  1898. m_JetErr = JetRetrieveColumn(
  1899. GetJetSessionID(),
  1900. columns.tableid,
  1901. columns.columnidcolumnname,
  1902. lpszColumnName,
  1903. sizeof(lpszColumnName),
  1904. &cbActual,
  1905. 0,
  1906. &jetRetInfo
  1907. );
  1908. if(IsSuccess() == FALSE)
  1909. continue;
  1910. NumChars = MultiByteToWideChar(
  1911. GetACP(),
  1912. MB_PRECOMPOSED,
  1913. lpszColumnName,
  1914. cbActual,
  1915. (m_Columns+index)->pszColumnName,
  1916. sizeof((m_Columns+index)->pszColumnName)
  1917. );
  1918. if(NumChars == 0)
  1919. {
  1920. SetLastJetError(JET_errInvalidParameter);
  1921. continue;
  1922. }
  1923. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1924. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1925. // retrieve column ID
  1926. m_JetErr = JetRetrieveColumn(
  1927. GetJetSessionID(),
  1928. columns.tableid,
  1929. columns.columnidcolumnid,
  1930. &((m_Columns+index)->colId),
  1931. sizeof((m_Columns+index)->colId),
  1932. &cbActual,
  1933. 0,
  1934. &jetRetInfo
  1935. );
  1936. if(IsSuccess() == FALSE)
  1937. continue;
  1938. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1939. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1940. m_JetErr = JetRetrieveColumn(
  1941. GetJetSessionID(),
  1942. columns.tableid,
  1943. columns.columnidcoltyp,
  1944. &((m_Columns+index)->colType),
  1945. sizeof((m_Columns+index)->colType),
  1946. &cbActual,
  1947. 0,
  1948. &jetRetInfo
  1949. );
  1950. if(IsSuccess() == FALSE)
  1951. continue;
  1952. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1953. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1954. m_JetErr = JetRetrieveColumn(
  1955. GetJetSessionID(),
  1956. columns.tableid,
  1957. columns.columnidcbMax,
  1958. &((m_Columns+index)->cbMaxLength),
  1959. sizeof((m_Columns+index)->cbMaxLength),
  1960. &cbActual,
  1961. 0,
  1962. &jetRetInfo
  1963. );
  1964. if(IsSuccess() == FALSE)
  1965. continue;
  1966. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1967. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1968. m_JetErr = JetRetrieveColumn(
  1969. GetJetSessionID(),
  1970. columns.tableid,
  1971. columns.columnidgrbit,
  1972. &((m_Columns+index)->jbGrbit),
  1973. sizeof((m_Columns+index)->jbGrbit),
  1974. &cbActual,
  1975. 0,
  1976. &jetRetInfo
  1977. );
  1978. DebugOutput(
  1979. _TEXT("Loaded Column name %s, Column Type %d, Column ID %d\n"),
  1980. m_Columns[index].pszColumnName,
  1981. m_Columns[index].colType,
  1982. m_Columns[index].colId
  1983. );
  1984. if(IsSuccess() == FALSE)
  1985. continue;
  1986. m_JetErr = JetMove(
  1987. GetJetSessionID(),
  1988. columns.tableid,
  1989. JET_MoveNext,
  1990. 0
  1991. );
  1992. }
  1993. if(GetLastJetError() == JET_errNoCurrentRecord && index >= columns.cRecord)
  1994. {
  1995. // otherwise - got to be a JetBlue bug here.
  1996. SetLastJetError(JET_errSuccess);
  1997. }
  1998. //
  1999. //
  2000. //
  2001. cleanup:
  2002. FreeJBstr(lpszTableName);
  2003. if(IsSuccess() == FALSE && m_Columns)
  2004. {
  2005. FreeMemory(m_Columns);
  2006. m_Columns = NULL;
  2007. m_NumColumns = 0;
  2008. }
  2009. return IsSuccess();
  2010. #endif
  2011. }
  2012. //-------------------------------------------------------------
  2013. JET_COLUMNID
  2014. JBTable::GetJetColumnID(
  2015. LPCTSTR pszColumnName
  2016. )
  2017. /*
  2018. */
  2019. {
  2020. int index;
  2021. index = GetJetColumnIndex(pszColumnName);
  2022. if(index < 0 || index >= m_NumJetColumns)
  2023. {
  2024. return (DWORD)JET_NIL_COLUMN;
  2025. }
  2026. return m_JetColumns[index].GetJetColumnID();
  2027. }
  2028. //-------------------------------------------------------------
  2029. int
  2030. JBTable::GetJetColumnIndex(
  2031. LPCTSTR pszColumnName
  2032. )
  2033. /*
  2034. */
  2035. {
  2036. if(m_JetColumns == NULL || m_NumJetColumns == 0)
  2037. {
  2038. SetLastJetError(JET_errNotInitialized);
  2039. return -1;
  2040. }
  2041. for(int index=0; index < m_NumJetColumns; index++)
  2042. {
  2043. if(_tcsicmp(m_JetColumns[index].GetJetColumnName(), pszColumnName) == 0)
  2044. break;
  2045. }
  2046. return (index >= m_NumJetColumns) ? -1 : index;
  2047. }
  2048. //-------------------------------------------------------------
  2049. JBColumn*
  2050. JBTable::FindColumnByIndex(
  2051. const int index
  2052. )
  2053. /*
  2054. */
  2055. {
  2056. if(m_JetColumns == NULL || m_NumJetColumns == 0)
  2057. {
  2058. SetLastJetError(JET_errNotInitialized);
  2059. return NULL;
  2060. }
  2061. if(index < 0 || index >= m_NumJetColumns)
  2062. {
  2063. SetLastJetError(JET_errInvalidParameter);
  2064. return NULL;
  2065. }
  2066. return m_JetColumns+index;
  2067. }
  2068. //--------------------------------------------------------------
  2069. JBColumn*
  2070. JBTable::FindColumnByColumnId(
  2071. const JET_COLUMNID JetColId
  2072. )
  2073. /*
  2074. */
  2075. {
  2076. if(m_JetColumns == NULL || m_NumJetColumns == 0)
  2077. {
  2078. SetLastJetError(JET_errNotInitialized);
  2079. return NULL;
  2080. }
  2081. for(int index=0; index < m_NumJetColumns; index++)
  2082. {
  2083. if(m_JetColumns[index].GetJetColumnID() == JetColId)
  2084. break;
  2085. }
  2086. return FindColumnByIndex( index );
  2087. }
  2088. //--------------------------------------------------------------
  2089. JBColumn*
  2090. JBTable::FindColumnByName(
  2091. LPCTSTR pszColumnName
  2092. )
  2093. /*
  2094. */
  2095. {
  2096. return FindColumnByIndex(GetJetColumnIndex(pszColumnName));
  2097. }
  2098. //--------------------------------------------------------------
  2099. BOOL
  2100. JBTable::BeginUpdate(
  2101. BOOL bUpdate /* false */
  2102. )
  2103. /*
  2104. */
  2105. {
  2106. if(GetTransactionLevel() == 0)
  2107. {
  2108. SetLastJetError(JET_errNotInTransaction);
  2109. JB_ASSERT(FALSE);
  2110. return FALSE;
  2111. }
  2112. SINGLE_JET_CALL;
  2113. m_JetErr = JetPrepareUpdate(
  2114. GetJetSessionID(),
  2115. GetJetTableID(),
  2116. (bUpdate) ? JET_prepReplace : JET_prepInsert
  2117. );
  2118. return IsSuccess();
  2119. }
  2120. //-------------------------------------------------------------
  2121. BOOL
  2122. JBTable::EndUpdate(
  2123. BOOL bDisacrd /* FALSE */
  2124. )
  2125. /*
  2126. */
  2127. {
  2128. BYTE pBookmark[JET_cbBookmarkMost+1];
  2129. DWORD cbActual = 0;
  2130. SINGLE_JET_CALL;
  2131. //
  2132. // Hack for work item table.
  2133. //
  2134. m_JetErr = JetUpdate(
  2135. GetJetSessionID(),
  2136. GetJetTableID(),
  2137. pBookmark,
  2138. JET_cbBookmarkMost,
  2139. &cbActual
  2140. );
  2141. if(IsSuccess() && m_InsertRepositionBookmark)
  2142. {
  2143. GotoBookmark(pBookmark, cbActual);
  2144. }
  2145. return IsSuccess();
  2146. }
  2147. //-------------------------------------------------------------
  2148. BOOL
  2149. JBTable::SetCurrentIndex(
  2150. LPCTSTR pszIndexName,
  2151. JET_GRBIT grbit /* JET_bitMoveFirst */
  2152. )
  2153. /*++
  2154. --*/
  2155. {
  2156. if(IsValid() == FALSE || m_InEnumeration == TRUE)
  2157. {
  2158. SetLastJetError(JET_errNotInitialized);
  2159. return FALSE;
  2160. }
  2161. //
  2162. // Can't be in enumeration and and try to set index
  2163. //
  2164. JB_ASSERT(m_InEnumeration == FALSE);
  2165. char* lpszIndexName=NULL;
  2166. if(ConvertWstrToJBstr(pszIndexName, &lpszIndexName) == FALSE)
  2167. {
  2168. SetLastJetError(JET_errInvalidParameter);
  2169. goto cleanup;
  2170. }
  2171. {
  2172. SINGLE_JET_CALL;
  2173. m_JetErr = JetSetCurrentIndex2(
  2174. GetJetSessionID(),
  2175. GetJetTableID(),
  2176. lpszIndexName,
  2177. grbit
  2178. );
  2179. }
  2180. if(IsSuccess())
  2181. {
  2182. m_InEnumeration = TRUE;
  2183. }
  2184. cleanup:
  2185. FreeJBstr(lpszIndexName);
  2186. return IsSuccess();
  2187. }
  2188. //-------------------------------------------------------------
  2189. BOOL
  2190. JBTable::EnumBegin(
  2191. LPCTSTR pszIndexName,
  2192. JET_GRBIT grbit /* JET_bitMoveFirst */
  2193. )
  2194. /*
  2195. */
  2196. {
  2197. if(m_InEnumeration == TRUE)
  2198. {
  2199. //
  2200. // Force terminate enumeration
  2201. //
  2202. EnumEnd();
  2203. }
  2204. return SetCurrentIndex(pszIndexName, grbit);
  2205. }
  2206. //-------------------------------------------------------------
  2207. JBTable::ENUM_RETCODE
  2208. JBTable::EnumNext(
  2209. JET_GRBIT crow /* JET_MoveNext */,
  2210. JET_GRBIT grbit /* 0 */
  2211. )
  2212. /*
  2213. */
  2214. {
  2215. if(m_InEnumeration == FALSE)
  2216. {
  2217. SetLastJetError(JET_errInvalidParameter);
  2218. return ENUM_ERROR;
  2219. }
  2220. if(IsValid() == FALSE)
  2221. {
  2222. SetLastJetError(JET_errNotInitialized);
  2223. return ENUM_ERROR;
  2224. }
  2225. ENUM_RETCODE retCode = ENUM_CONTINUE;
  2226. while( retCode == ENUM_CONTINUE )
  2227. {
  2228. MoveToRecord(crow, grbit);
  2229. switch(m_JetErr)
  2230. {
  2231. case JET_errSuccess:
  2232. retCode = ENUM_SUCCESS;
  2233. break;
  2234. case JET_errNoCurrentRecord:
  2235. retCode = ENUM_END;
  2236. break;
  2237. case JET_errRecordDeleted:
  2238. retCode = ENUM_CONTINUE;
  2239. break;
  2240. default:
  2241. retCode = ENUM_ERROR;
  2242. }
  2243. }
  2244. return retCode;
  2245. }
  2246. //-------------------------------------------------------------
  2247. BOOL
  2248. JBTable::SeekToKey(
  2249. JBKeyBase* key,
  2250. DWORD dwSeachParam,
  2251. JET_GRBIT jetseekgrbit /* =JET_bitSeekGE */
  2252. )
  2253. /*
  2254. */
  2255. {
  2256. if(IsValid() == FALSE)
  2257. {
  2258. SetLastJetError(JET_errNotInitialized);
  2259. return FALSE;
  2260. }
  2261. #ifdef DEBUG_SEEK
  2262. LPTSTR szKey=key->GetIndexKey();
  2263. #endif
  2264. EnumBegin(
  2265. key->GetIndexName(),
  2266. JET_bitMoveFirst
  2267. );
  2268. if(IsSuccess() == FALSE)
  2269. return FALSE;
  2270. if(key->IsEmptyValue() == TRUE)
  2271. {
  2272. return TRUE;
  2273. }
  2274. PVOID pbData;
  2275. unsigned long cbData;
  2276. JET_GRBIT key_grbit=JET_bitNewKey;
  2277. SetLastJetError(JET_errSuccess);
  2278. for(DWORD dwComponent=0;
  2279. dwComponent < key->GetNumKeyComponents();
  2280. dwComponent++)
  2281. {
  2282. if(key->GetSearchKey(dwComponent, &pbData, &cbData, &key_grbit, dwSeachParam) == FALSE)
  2283. break;
  2284. if(MakeKey(pbData, cbData, key_grbit) == FALSE)
  2285. break;
  2286. }
  2287. #ifdef DEBUG_SEEK
  2288. PVOID pb=NULL;
  2289. DWORD cb=0;
  2290. unsigned long actual;
  2291. SINGLE_JET_CALL;
  2292. m_JetErr = JetRetrieveKey(
  2293. GetJetSessionID(),
  2294. GetJetTableID(),
  2295. pb,
  2296. cb,
  2297. &actual,
  2298. 0
  2299. );
  2300. pb = (PVOID)AllocateMemory(actual);
  2301. cb = actual;
  2302. m_JetErr = JetRetrieveKey(
  2303. GetJetSessionID(),
  2304. GetJetTableID(),
  2305. pb,
  2306. cb,
  2307. &actual,
  2308. 0
  2309. );
  2310. FreeMemory(pb);
  2311. #endif
  2312. return IsSuccess() ? SeekValue(jetseekgrbit) : FALSE;
  2313. }
  2314. //-------------------------------------------------------------
  2315. BOOL
  2316. JBTable::EnumBegin(
  2317. JBKeyBase* key,
  2318. DWORD dwSearchParam
  2319. )
  2320. /*
  2321. */
  2322. {
  2323. if(IsValid() == FALSE)
  2324. {
  2325. SetLastJetError(JET_errNotInitialized);
  2326. return FALSE;
  2327. }
  2328. if(m_InEnumeration == TRUE)
  2329. {
  2330. // what do we do???
  2331. }
  2332. return SeekToKey(key, dwSearchParam);
  2333. }
  2334. //-------------------------------------------------------------
  2335. BOOL
  2336. JBTable::GetCurrentIndex(
  2337. LPTSTR pszIndexName,
  2338. unsigned long* bufferSize
  2339. )
  2340. /*
  2341. */
  2342. {
  2343. char lpszIndexName[MAX_JETBLUE_NAME_LENGTH+1];
  2344. int NumChars=0;
  2345. SINGLE_JET_CALL;
  2346. m_JetErr = JetGetCurrentIndex(
  2347. GetJetSessionID(),
  2348. GetJetTableID(),
  2349. lpszIndexName,
  2350. sizeof(lpszIndexName)
  2351. );
  2352. if(IsSuccess() == FALSE)
  2353. goto cleanup;
  2354. NumChars = MultiByteToWideChar(
  2355. GetACP(),
  2356. MB_PRECOMPOSED,
  2357. lpszIndexName,
  2358. -1,
  2359. pszIndexName,
  2360. *bufferSize
  2361. );
  2362. if(NumChars == 0)
  2363. {
  2364. SetLastJetError(JET_errInvalidParameter);
  2365. goto cleanup;
  2366. }
  2367. *bufferSize = NumChars;
  2368. cleanup:
  2369. return IsSuccess();
  2370. }
  2371. //-------------------------------------------------------------
  2372. BOOL
  2373. JBTable::GetBookmark(
  2374. PVOID pbBuffer,
  2375. PDWORD pcbBufSize
  2376. )
  2377. /*++
  2378. --*/
  2379. {
  2380. DWORD cbBufferSize = *pcbBufSize;
  2381. SINGLE_JET_CALL;
  2382. m_JetErr = JetGetBookmark(
  2383. GetJetSessionID(),
  2384. GetJetTableID(),
  2385. pbBuffer,
  2386. cbBufferSize,
  2387. pcbBufSize
  2388. );
  2389. if(m_JetErr == JET_errBufferTooSmall)
  2390. {
  2391. SetLastJetError(m_JetErr);
  2392. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  2393. }
  2394. return IsSuccess();
  2395. }
  2396. //-------------------------------------------------------------
  2397. BOOL
  2398. JBTable::GotoBookmark(
  2399. PVOID pbBuffer,
  2400. DWORD cbBuffer
  2401. )
  2402. /*++
  2403. --*/
  2404. {
  2405. SINGLE_JET_CALL;
  2406. m_JetErr = JetGotoBookmark(
  2407. GetJetSessionID(),
  2408. GetJetTableID(),
  2409. pbBuffer,
  2410. cbBuffer
  2411. );
  2412. return IsSuccess();
  2413. }
  2414. //-------------------------------------------------------------
  2415. BOOL
  2416. JBTable::ReadLock()
  2417. {
  2418. SINGLE_JET_CALL;
  2419. m_JetErr = JetGetLock(
  2420. GetJetSessionID(),
  2421. GetJetTableID(),
  2422. JET_bitReadLock
  2423. );
  2424. return IsSuccess();
  2425. }
  2426. //-------------------------------------------------------------
  2427. BOOL
  2428. JBTable::WriteLock()
  2429. {
  2430. SINGLE_JET_CALL;
  2431. m_JetErr = JetGetLock(
  2432. GetJetSessionID(),
  2433. GetJetTableID(),
  2434. JET_bitWriteLock
  2435. );
  2436. return IsSuccess();
  2437. }
  2438. //-------------------------------------------------------------
  2439. BOOL
  2440. JBTable::RetrieveKey(
  2441. PVOID pbData,
  2442. unsigned long cbData,
  2443. unsigned long* pcbActual,
  2444. JET_GRBIT grbit
  2445. )
  2446. /*
  2447. */
  2448. {
  2449. unsigned long cbActual;
  2450. SINGLE_JET_CALL;
  2451. m_JetErr = JetRetrieveKey(
  2452. GetJetSessionID(),
  2453. GetJetTableID(),
  2454. pbData,
  2455. cbData,
  2456. (pcbActual) ? pcbActual : &cbActual,
  2457. grbit // user2.doc - unuse.
  2458. );
  2459. return IsSuccess();
  2460. }
  2461. //-------------------------------------------------------------
  2462. BOOL
  2463. JBTable::MoveToRecord(
  2464. long crow,
  2465. JET_GRBIT grbit
  2466. )
  2467. /*
  2468. */
  2469. {
  2470. SINGLE_JET_CALL;
  2471. m_JetErr = JetMove(
  2472. GetJetSessionID(),
  2473. GetJetTableID(),
  2474. crow,
  2475. grbit
  2476. );
  2477. return IsSuccess();
  2478. }
  2479. //-------------------------------------------------------------
  2480. unsigned long
  2481. JBTable::GetIndexRecordCount(
  2482. unsigned long max
  2483. )
  2484. /*
  2485. */
  2486. {
  2487. unsigned long count;
  2488. SINGLE_JET_CALL;
  2489. m_JetErr = JetIndexRecordCount(
  2490. GetJetSessionID(),
  2491. GetJetTableID(),
  2492. &count,
  2493. max
  2494. );
  2495. return IsSuccess() ? count : 0;
  2496. }
  2497. //-------------------------------------------------------------
  2498. BOOL
  2499. JBTable::MakeKey(
  2500. PVOID pbData,
  2501. unsigned long cbData,
  2502. JET_GRBIT grbit
  2503. )
  2504. /*
  2505. */
  2506. {
  2507. SINGLE_JET_CALL;
  2508. m_JetErr = JetMakeKey(
  2509. GetJetSessionID(),
  2510. GetJetTableID(),
  2511. pbData,
  2512. cbData,
  2513. grbit
  2514. );
  2515. return IsSuccess();
  2516. }
  2517. //-------------------------------------------------------------
  2518. BOOL
  2519. JBTable::SeekValue(
  2520. JET_GRBIT grbit
  2521. )
  2522. /*
  2523. */
  2524. {
  2525. SINGLE_JET_CALL;
  2526. m_JetErr = JetSeek(
  2527. GetJetSessionID(),
  2528. GetJetTableID(),
  2529. grbit
  2530. );
  2531. return IsSuccess();
  2532. }
  2533. //-------------------------------------------------------------
  2534. BOOL
  2535. JBTable::DeleteRecord()
  2536. /*
  2537. */
  2538. {
  2539. SINGLE_JET_CALL;
  2540. // must have current record set
  2541. m_JetErr = JetDelete(
  2542. GetJetSessionID(),
  2543. GetJetTableID()
  2544. );
  2545. return IsSuccess();
  2546. }
  2547. //
  2548. //////////////////////////////////////////////////////////////
  2549. //
  2550. CLASS_PRIVATE void
  2551. JBColumn::Cleanup()
  2552. /*
  2553. */
  2554. {
  2555. memset(m_szColumnName, 0, sizeof(m_szColumnName));
  2556. }
  2557. //-----------------------------------------------------------
  2558. JBColumn::JBColumn(JBTable* pJetTable) :
  2559. m_pJetTable(pJetTable),
  2560. m_JetColId(0),
  2561. m_JetColType(JET_coltypNil),
  2562. m_JetMaxColLength(0),
  2563. m_JetGrbit(0),
  2564. m_JetColCodePage(TLS_JETBLUE_COLUMN_CODE_PAGE),
  2565. m_JetColCountryCode(TLS_JETBLUE_COLUMN_COUNTRY_CODE),
  2566. m_JetColLangId(TLS_JETBLUE_COLUMN_LANGID),
  2567. m_cbActual(0),
  2568. m_pbDefValue(NULL),
  2569. m_cbDefValue(0),
  2570. m_JetNullColumn(FALSE)
  2571. /*
  2572. */
  2573. {
  2574. Cleanup();
  2575. }
  2576. //-----------------------------------------------------------
  2577. CLASS_PRIVATE JET_ERR
  2578. JBColumn::RetrieveColumnValue(
  2579. IN JET_SESID sesid,
  2580. IN JET_TABLEID tableid,
  2581. IN JET_COLUMNID columnid,
  2582. IN OUT PVOID pbBuffer,
  2583. IN unsigned long cbBuffer,
  2584. IN unsigned long offset
  2585. )
  2586. /*
  2587. */
  2588. {
  2589. m_JetRetInfo.cbStruct = sizeof(m_JetRetInfo);
  2590. m_JetRetInfo.ibLongValue = offset;
  2591. m_JetNullColumn = FALSE;
  2592. m_cbActual = 0;
  2593. SINGLE_JET_CALL;
  2594. //
  2595. // JETBLUE bug??? passing zeror buffer size returns Column NULL
  2596. //
  2597. m_JetErr = JetRetrieveColumn(
  2598. sesid,
  2599. tableid,
  2600. columnid,
  2601. pbBuffer,
  2602. cbBuffer,
  2603. &m_cbActual,
  2604. 0,
  2605. NULL // &m_JetRetInfo
  2606. );
  2607. if(m_JetErr == JET_wrnColumnNull)
  2608. m_JetNullColumn = TRUE;
  2609. return IsSuccess();
  2610. }
  2611. //-----------------------------------------------------------
  2612. CLASS_PRIVATE BOOL
  2613. JBColumn::LoadJetColumnInfoFromJet(
  2614. const JET_COLUMNLIST* pColumnList
  2615. )
  2616. /*
  2617. */
  2618. {
  2619. char lpszColumnName[MAX_JETBLUE_NAME_LENGTH+1];
  2620. int NumChars;
  2621. //
  2622. // retrieve column name
  2623. //
  2624. RetrieveColumnValue(
  2625. GetJetSessionID(),
  2626. pColumnList->tableid,
  2627. pColumnList->columnidcolumnname,
  2628. lpszColumnName,
  2629. sizeof(lpszColumnName)
  2630. );
  2631. if(IsSuccess() == FALSE)
  2632. goto cleanup;
  2633. NumChars = MultiByteToWideChar(
  2634. GetACP(),
  2635. MB_PRECOMPOSED,
  2636. lpszColumnName,
  2637. m_cbActual,
  2638. m_szColumnName,
  2639. sizeof(m_szColumnName)/sizeof(m_szColumnName[0])
  2640. );
  2641. if(NumChars == 0)
  2642. {
  2643. SetLastJetError(JET_errInvalidParameter);
  2644. goto cleanup;
  2645. }
  2646. //DebugOutput(
  2647. // _TEXT("Load column %s"),
  2648. // m_szColumnName
  2649. // );
  2650. //
  2651. // retrieve column ID
  2652. //
  2653. RetrieveColumnValue(
  2654. GetJetSessionID(),
  2655. pColumnList->tableid,
  2656. pColumnList->columnidcolumnid,
  2657. &m_JetColId,
  2658. sizeof(m_JetColId)
  2659. );
  2660. if(IsSuccess() == FALSE)
  2661. goto cleanup;
  2662. //DebugOutput(
  2663. // _TEXT("\tColId - %d"),
  2664. // m_JetColId
  2665. // );
  2666. //
  2667. // Retrieve Column Type
  2668. //
  2669. RetrieveColumnValue(
  2670. GetJetSessionID(),
  2671. pColumnList->tableid,
  2672. pColumnList->columnidcoltyp,
  2673. &m_JetColType,
  2674. sizeof(m_JetColType)
  2675. );
  2676. if(IsSuccess() == FALSE)
  2677. goto cleanup;
  2678. //DebugOutput(
  2679. // _TEXT("\tCol Type %d"),
  2680. // m_JetColType
  2681. // );
  2682. //
  2683. // Retrieve Max. length for LongText and Long Binary
  2684. //
  2685. RetrieveColumnValue(
  2686. GetJetSessionID(),
  2687. pColumnList->tableid,
  2688. pColumnList->columnidcbMax,
  2689. &m_JetMaxColLength,
  2690. sizeof(m_JetMaxColLength)
  2691. );
  2692. if(IsSuccess() == FALSE)
  2693. goto cleanup;
  2694. //DebugOutput(
  2695. // _TEXT("\tMax Col Length %d"),
  2696. // m_JetMaxColLength
  2697. // );
  2698. //
  2699. // Retrieve Column Grbit
  2700. //
  2701. RetrieveColumnValue(
  2702. GetJetSessionID(),
  2703. pColumnList->tableid,
  2704. pColumnList->columnidgrbit,
  2705. &m_JetGrbit,
  2706. sizeof(m_JetGrbit)
  2707. );
  2708. if(IsSuccess() == FALSE)
  2709. goto cleanup;
  2710. //DebugOutput(
  2711. // _TEXT("\tCol grbit %d"),
  2712. // m_JetGrbit
  2713. // );
  2714. cleanup:
  2715. //DebugOutput(
  2716. // _TEXT("\n")
  2717. // );
  2718. return IsSuccess();
  2719. }
  2720. //-----------------------------------------------------------
  2721. BOOL
  2722. JBColumn::IsValid() const
  2723. /*
  2724. */
  2725. {
  2726. return m_pJetTable != NULL && m_pJetTable->IsValid();
  2727. }
  2728. //-----------------------------------------------------------
  2729. BOOL
  2730. JBColumn::InsertColumn(
  2731. PVOID pbData,
  2732. unsigned long cbData,
  2733. unsigned long offset
  2734. )
  2735. /*
  2736. */
  2737. {
  2738. //JET_SETINFO setinfo;
  2739. if(IsValid() == FALSE)
  2740. {
  2741. SetLastJetError(JET_errInvalidParameter);
  2742. return IsSuccess();
  2743. }
  2744. SINGLE_JET_CALL;
  2745. // if(GetJetColumnType() == JET_coltypLongText || GetJetColumnType() == JET_coltypLongBinary)
  2746. if(pbData == NULL || cbData == 0)
  2747. {
  2748. m_JetErr = JetSetColumn(
  2749. GetJetSessionID(),
  2750. GetJetTableID(),
  2751. GetJetColumnID(),
  2752. 0,
  2753. 0,
  2754. JET_bitSetZeroLength,
  2755. NULL
  2756. );
  2757. if(IsSuccess() == FALSE)
  2758. return FALSE;
  2759. m_JetErr = JetSetColumn(
  2760. GetJetSessionID(),
  2761. GetJetTableID(),
  2762. GetJetColumnID(),
  2763. 0,
  2764. 0,
  2765. 0,
  2766. NULL
  2767. );
  2768. if(IsSuccess() == FALSE)
  2769. return FALSE;
  2770. }
  2771. m_JetErr = JetSetColumn(
  2772. GetJetSessionID(),
  2773. GetJetTableID(),
  2774. GetJetColumnID(),
  2775. pbData,
  2776. cbData,
  2777. 0,
  2778. NULL
  2779. );
  2780. return IsSuccess();
  2781. }
  2782. //-----------------------------------------------------------
  2783. BOOL
  2784. JBColumn::FetchColumn(
  2785. PVOID pbData,
  2786. unsigned long cbData,
  2787. unsigned long starting_offset
  2788. )
  2789. /*
  2790. pass NULL and 0 to determine buffer size needed.
  2791. */
  2792. {
  2793. if(IsValid() == FALSE)
  2794. {
  2795. SetLastJetError(JET_errNotInitialized);
  2796. }
  2797. else
  2798. {
  2799. RetrieveColumnValue(
  2800. GetJetSessionID(),
  2801. GetJetTableID(),
  2802. GetJetColumnID(),
  2803. pbData,
  2804. cbData,
  2805. starting_offset
  2806. );
  2807. }
  2808. return IsSuccess();
  2809. }