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.

3423 lines
77 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. m_JetErr = JetCloseTable(
  1000. GetJetSessionID(),
  1001. tableid
  1002. );
  1003. if(IsSuccess())
  1004. {
  1005. m_TableOpened--;
  1006. }
  1007. return IsSuccess();
  1008. }
  1009. //--------------------------------------------------------------------
  1010. CLASS_PRIVATE JET_TABLEID
  1011. JBDatabase::CreateJetTable(
  1012. LPCTSTR pszTableName,
  1013. unsigned long lPage, // 0
  1014. unsigned long lDensity // 20
  1015. )
  1016. /*
  1017. */
  1018. {
  1019. JET_TABLEID tableid = JET_tableidNil;
  1020. JB_STRING lpszTableName=NULL;
  1021. if(IsValid() == FALSE)
  1022. {
  1023. SetLastJetError(JET_errNotInitialized);
  1024. goto cleanup;
  1025. }
  1026. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  1027. {
  1028. SetLastJetError(JET_errInvalidParameter);
  1029. goto cleanup;
  1030. }
  1031. {
  1032. SINGLE_JET_CALL;
  1033. m_JetErr = JetCreateTable(
  1034. GetJetSessionID(),
  1035. m_JetDbId,
  1036. lpszTableName,
  1037. lPage,
  1038. lDensity,
  1039. &tableid
  1040. );
  1041. }
  1042. if(IsSuccess() == FALSE)
  1043. {
  1044. goto cleanup;
  1045. }
  1046. m_TableOpened++;
  1047. cleanup:
  1048. FreeJBstr(lpszTableName);
  1049. return tableid;
  1050. }
  1051. //--------------------------------------------------------------------
  1052. CLASS_PRIVATE JET_TABLEID
  1053. JBDatabase::CreateJetTableEx(
  1054. LPCTSTR pszTableName,
  1055. const PTLSJBTable table_attribute,
  1056. const PTLSJBColumn columns,
  1057. const DWORD num_columns,
  1058. const PTLSJBIndex table_index,
  1059. const DWORD num_table_index
  1060. )
  1061. /*
  1062. */
  1063. {
  1064. JET_TABLEID tableid = JET_tableidNil;
  1065. JB_STRING lpszTableName=NULL;
  1066. JET_TABLECREATE table_create;
  1067. JET_COLUMNCREATE* column_create=NULL;
  1068. JET_INDEXCREATE* index_create=NULL;
  1069. DWORD index=0;
  1070. SINGLE_JET_CALL;
  1071. table_create.szTableName = NULL;
  1072. table_create.szTemplateTableName = NULL;
  1073. if(IsValid() == FALSE)
  1074. {
  1075. SetLastJetError(JET_errNotInitialized);
  1076. goto cleanup;
  1077. }
  1078. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  1079. {
  1080. SetLastJetError(JET_errInvalidParameter);
  1081. goto cleanup;
  1082. }
  1083. table_create.cbStruct = sizeof(JET_TABLECREATE);
  1084. table_create.szTableName = lpszTableName;
  1085. if(ConvertWstrToJBstr(table_attribute->pszTemplateTableName, &table_create.szTemplateTableName) == FALSE)
  1086. {
  1087. SetLastJetError(JET_errInvalidParameter);
  1088. goto cleanup;
  1089. }
  1090. table_create.ulPages = table_attribute->ulPages;
  1091. table_create.ulDensity = (table_attribute->ulDensity < 20 || table_attribute->ulDensity > 100) ?
  1092. TLS_JETBLUE_DEFAULT_TABLE_DENSITY : table_attribute->ulDensity;
  1093. table_create.grbit = table_attribute->jbGrbit;
  1094. //
  1095. // form a JET_TABLECREATE structure
  1096. //
  1097. column_create = (JET_COLUMNCREATE *)AllocateMemory(
  1098. sizeof(JET_COLUMNCREATE) * num_columns
  1099. );
  1100. if(column_create == NULL)
  1101. {
  1102. SetLastJetError(JET_errOutOfMemory);
  1103. goto cleanup;
  1104. }
  1105. index_create = (JET_INDEXCREATE *)AllocateMemory(
  1106. sizeof(JET_INDEXCREATE) * num_table_index
  1107. );
  1108. if(index_create == NULL)
  1109. {
  1110. SetLastJetError(JET_errOutOfMemory);
  1111. goto cleanup;
  1112. }
  1113. for(index=0; index < num_columns; index++)
  1114. {
  1115. if(ConvertTLSJbColumnDefToJbColumnCreate( columns+index, column_create+index ) == FALSE)
  1116. {
  1117. goto cleanup;
  1118. }
  1119. }
  1120. for(index=0; index < num_table_index; index++)
  1121. {
  1122. if(ConvertTlsJBTableIndexDefToJbIndexCreate( table_index+index, index_create+index ) == FALSE)
  1123. goto cleanup;
  1124. }
  1125. table_create.rgcolumncreate = column_create;
  1126. table_create.cColumns = num_columns;
  1127. table_create.rgindexcreate = index_create;
  1128. table_create.cIndexes = num_table_index;
  1129. m_JetErr = JetCreateTableColumnIndex(
  1130. GetJetSessionID(),
  1131. GetJetDatabaseID(),
  1132. &table_create
  1133. );
  1134. if(IsSuccess() == TRUE)
  1135. {
  1136. tableid = table_create.tableid;
  1137. }
  1138. cleanup:
  1139. if(column_create != NULL)
  1140. {
  1141. for(index=0; index < num_columns; index++)
  1142. {
  1143. if(column_create[index].szColumnName != NULL)
  1144. {
  1145. FreeJBstr(column_create[index].szColumnName);
  1146. }
  1147. }
  1148. FreeMemory(column_create);
  1149. }
  1150. if(index_create != NULL)
  1151. {
  1152. for(index=0; index < num_table_index; index++)
  1153. {
  1154. if(index_create[index].szIndexName != NULL)
  1155. {
  1156. FreeJBstr(index_create[index].szIndexName);
  1157. }
  1158. if(index_create[index].szKey != NULL)
  1159. {
  1160. FreeJBstr(index_create[index].szKey);
  1161. }
  1162. }
  1163. FreeMemory(index_create);
  1164. }
  1165. if(table_create.szTemplateTableName)
  1166. FreeJBstr(table_create.szTemplateTableName);
  1167. if(table_create.szTableName)
  1168. FreeJBstr(table_create.szTableName);
  1169. return tableid;
  1170. }
  1171. //--------------------------------------------------------------------
  1172. JET_TABLEID
  1173. JBDatabase::CreateTable(
  1174. LPCTSTR pszTableName,
  1175. unsigned long lPage, // 0
  1176. unsigned long lDensity // 20
  1177. )
  1178. /*
  1179. */
  1180. {
  1181. JET_TABLEID tableid;
  1182. tableid = CreateJetTable(
  1183. pszTableName,
  1184. lPage,
  1185. lDensity
  1186. );
  1187. if(tableid == JET_tableidNil)
  1188. {
  1189. m_JetErr = GetLastJetError();
  1190. }
  1191. return tableid;
  1192. }
  1193. //-------------------------------------------------------------------
  1194. JET_TABLEID
  1195. JBDatabase::CreateTableEx(
  1196. LPCTSTR pszTableName,
  1197. const PTLSJBTable table_attribute,
  1198. const PTLSJBColumn columns,
  1199. DWORD num_columns,
  1200. const PTLSJBIndex index,
  1201. DWORD num_index
  1202. )
  1203. /*
  1204. */
  1205. {
  1206. JET_TABLEID tableid;
  1207. tableid = CreateJetTableEx(
  1208. pszTableName,
  1209. table_attribute,
  1210. columns,
  1211. num_columns,
  1212. index,
  1213. num_index
  1214. );
  1215. if(tableid == JET_tableidNil)
  1216. {
  1217. m_JetErr = GetLastJetError();
  1218. }
  1219. return tableid;
  1220. }
  1221. //--------------------------------------------------------------------
  1222. CLASS_PRIVATE BOOL
  1223. JBDatabase::CloseTable(
  1224. JET_TABLEID tableid
  1225. )
  1226. /*
  1227. ? Verify this table ID is from this DB/Session
  1228. */
  1229. {
  1230. return CloseJetTable( tableid );
  1231. }
  1232. //--------------------------------------------------------------------
  1233. BOOL
  1234. JBDatabase::DeleteTable(
  1235. IN LPCTSTR pszTableName
  1236. )
  1237. /*
  1238. TODO - ? verify this table is in this database
  1239. */
  1240. {
  1241. JB_STRING lpszTableName=NULL;
  1242. if(IsValid() == FALSE)
  1243. {
  1244. SetLastJetError(JET_errNotInitialized);
  1245. goto cleanup;
  1246. }
  1247. if(ConvertWstrToJBstr(pszTableName, &lpszTableName) == FALSE)
  1248. {
  1249. SetLastJetError(JET_errInvalidParameter);
  1250. goto cleanup;
  1251. }
  1252. {
  1253. SINGLE_JET_CALL;
  1254. m_JetErr = JetDeleteTable(
  1255. GetJetSessionID(),
  1256. GetJetDatabaseID(),
  1257. lpszTableName
  1258. );
  1259. }
  1260. //if(IsSuccess() == FALSE)
  1261. // goto cleanup;
  1262. cleanup:
  1263. FreeJBstr(lpszTableName);
  1264. return IsSuccess();
  1265. }
  1266. //--------------------------------------------------------------------
  1267. BOOL
  1268. JBDatabase::OpenDatabase(
  1269. LPCTSTR szFile,
  1270. LPCTSTR szConnect, // NULL
  1271. JET_GRBIT grbit // 0
  1272. )
  1273. /*
  1274. */
  1275. {
  1276. m_JetDbId = m_JetSession.OpenJetDatabase(
  1277. szFile,
  1278. szConnect,
  1279. grbit
  1280. );
  1281. if(m_JetDbId == JET_dbidNil)
  1282. {
  1283. m_JetErr = m_JetSession.GetLastJetError();
  1284. }
  1285. else
  1286. {
  1287. _tcscpy(m_szDatabaseFile, szFile);
  1288. }
  1289. return m_JetDbId != JET_dbidNil;
  1290. }
  1291. //--------------------------------------------------------------------
  1292. BOOL
  1293. JBDatabase::CreateDatabase(
  1294. LPCTSTR szFile,
  1295. LPCTSTR szConnect, // NULL
  1296. JET_GRBIT grbit // 0
  1297. )
  1298. /*
  1299. */
  1300. {
  1301. m_JetDbId = m_JetSession.CreateJetDatabase(
  1302. szFile,
  1303. szConnect,
  1304. grbit
  1305. );
  1306. if(m_JetDbId == JET_dbidNil)
  1307. {
  1308. m_JetErr = m_JetSession.GetLastJetError();
  1309. }
  1310. else
  1311. {
  1312. _tcscpy(m_szDatabaseFile, szFile);
  1313. }
  1314. return m_JetDbId != JET_dbidNil;
  1315. }
  1316. //////////////////////////////////////////////////////////////////////
  1317. //
  1318. // JBTable
  1319. //
  1320. //////////////////////////////////////////////////////////////////////
  1321. JBColumn JBTable::m_ErrColumn;
  1322. JBTable::JBTable(
  1323. JBDatabase& JetDatabase,
  1324. LPCTSTR pszTableName,
  1325. JET_TABLEID tableid
  1326. ) :
  1327. JBError(),
  1328. m_JetDatabase(JetDatabase),
  1329. m_JetTableId(tableid),
  1330. m_JetColumns(NULL),
  1331. m_NumJetColumns(0),
  1332. m_InEnumeration(FALSE),
  1333. m_InsertRepositionBookmark(FALSE)
  1334. /*
  1335. */
  1336. {
  1337. if(pszTableName)
  1338. {
  1339. _tcscpy(m_szTableName, pszTableName);
  1340. }
  1341. else
  1342. {
  1343. memset(m_szTableName, 0, sizeof(m_szTableName));
  1344. }
  1345. }
  1346. //--------------------------------------------------------------------
  1347. JBTable::JBTable(
  1348. JBTable& jbTable
  1349. ) :
  1350. JBError(),
  1351. m_JetDatabase(jbTable.GetJetDatabase()),
  1352. m_JetColumns(NULL),
  1353. m_NumJetColumns(0),
  1354. m_InEnumeration(FALSE)
  1355. /*
  1356. */
  1357. {
  1358. // duplicate jet cursor
  1359. _tcscpy(m_szTableName, jbTable.GetTableName());
  1360. m_JetTableId = m_JetDatabase.DuplicateJetCursor(
  1361. jbTable.GetJetTableID(),
  1362. 0
  1363. );
  1364. if(m_JetTableId == JET_tableidNil)
  1365. {
  1366. m_JetErr = m_JetDatabase.GetLastJetError();
  1367. }
  1368. }
  1369. //--------------------------------------------------------------------
  1370. JBTable::~JBTable()
  1371. {
  1372. if(m_JetTableId == JET_tableidNil)
  1373. return;
  1374. CloseTable();
  1375. }
  1376. //--------------------------------------------------------------------
  1377. CLASS_PRIVATE JET_COLUMNID
  1378. JBTable::AddJetColumn(
  1379. LPCTSTR pszColumnName,
  1380. const JET_COLUMNDEF* pColumnDef,
  1381. const PVOID pbDefaultValue, // NULL
  1382. const unsigned long cbDefaultValue // 0
  1383. )
  1384. /*
  1385. */
  1386. {
  1387. DebugOutput(
  1388. _TEXT("Adding column %s to table %s, type %d\n"),
  1389. pszColumnName,
  1390. GetTableName(),
  1391. pColumnDef->coltyp
  1392. );
  1393. JB_STRING lpszColumnName=NULL;
  1394. JET_COLUMNID columnid = (DWORD)JET_NIL_COLUMN;
  1395. if(IsValid() == FALSE)
  1396. {
  1397. SetLastJetError(JET_errInvalidDatabaseId);
  1398. goto cleanup;
  1399. }
  1400. if(ConvertWstrToJBstr(pszColumnName, &lpszColumnName) == FALSE)
  1401. {
  1402. SetLastJetError(JET_errInvalidDatabaseId);
  1403. goto cleanup;
  1404. }
  1405. {
  1406. SINGLE_JET_CALL;
  1407. m_JetErr = JetAddColumn(
  1408. GetJetSessionID(),
  1409. GetJetTableID(),
  1410. lpszColumnName,
  1411. pColumnDef,
  1412. pbDefaultValue,
  1413. cbDefaultValue,
  1414. &columnid
  1415. );
  1416. }
  1417. cleanup:
  1418. DebugOutput(
  1419. _TEXT("AddJetColumn returns %d\n"),
  1420. GetLastJetError()
  1421. );
  1422. FreeJBstr(lpszColumnName);
  1423. return columnid;
  1424. }
  1425. //--------------------------------------------------------------------
  1426. BOOL
  1427. JBTable::AddIndex(
  1428. JBKeyBase* key
  1429. )
  1430. /*
  1431. */
  1432. {
  1433. return AddJetIndex(
  1434. key->GetIndexName(),
  1435. key->GetIndexKey(),
  1436. key->GetKeyLength(),
  1437. key->GetJetGrbit(),
  1438. key->GetJetDensity()
  1439. );
  1440. }
  1441. //--------------------------------------------------------------------
  1442. BOOL
  1443. JBTable::AddJetIndex(
  1444. LPCTSTR pszIndexName,
  1445. LPCTSTR pszKey,
  1446. unsigned long cbKey,
  1447. JET_GRBIT grbit, /* 0 */
  1448. unsigned long lDensity /* 20 */
  1449. )
  1450. /*
  1451. */
  1452. {
  1453. DebugOutput(
  1454. _TEXT("Adding Index %s to table %s\n"),
  1455. pszIndexName,
  1456. GetTableName()
  1457. );
  1458. JB_STRING lpszIndexName=NULL;
  1459. JB_STRING lpszKeyName=NULL;
  1460. if(IsValid() == FALSE)
  1461. {
  1462. SetLastJetError(JET_errInvalidDatabaseId);
  1463. goto cleanup;
  1464. }
  1465. if(ConvertWstrToJBstr(pszIndexName, &lpszIndexName) == FALSE)
  1466. {
  1467. SetLastJetError(JET_errInvalidDatabaseId);
  1468. goto cleanup;
  1469. }
  1470. if(ConvertMWstrToMJBstr(pszKey, cbKey, &lpszKeyName) == FALSE)
  1471. {
  1472. SetLastJetError(JET_errInvalidDatabaseId);
  1473. goto cleanup;
  1474. }
  1475. {
  1476. SINGLE_JET_CALL;
  1477. m_JetErr = JetCreateIndex(
  1478. GetJetSessionID(),
  1479. GetJetTableID(),
  1480. lpszIndexName,
  1481. grbit,
  1482. lpszKeyName,
  1483. cbKey,
  1484. lDensity
  1485. );
  1486. }
  1487. cleanup:
  1488. DebugOutput(
  1489. _TEXT("Adding index %s returns %d\n"),
  1490. pszIndexName,
  1491. GetLastJetError()
  1492. );
  1493. FreeJBstr(lpszIndexName);
  1494. FreeJBstr(lpszKeyName);
  1495. return IsSuccess();
  1496. }
  1497. BOOL
  1498. JBTable::DoesIndexExist(
  1499. LPCTSTR pszIndexName
  1500. )
  1501. {
  1502. JB_STRING lpszIndexName=NULL;
  1503. JET_INDEXID idx;
  1504. if(IsValid() == FALSE)
  1505. {
  1506. SetLastJetError(JET_errInvalidDatabaseId);
  1507. goto cleanup;
  1508. }
  1509. if(ConvertWstrToJBstr(pszIndexName, &lpszIndexName) == FALSE)
  1510. {
  1511. SetLastJetError(JET_errInvalidDatabaseId);
  1512. goto cleanup;
  1513. }
  1514. {
  1515. SINGLE_JET_CALL;
  1516. m_JetErr = JetGetTableIndexInfo(
  1517. GetJetSessionID(),
  1518. GetJetTableID(),
  1519. lpszIndexName,
  1520. &idx,
  1521. sizeof(JET_INDEXID),
  1522. JET_IdxInfoIndexId
  1523. );
  1524. // if this succeeds, the index exists
  1525. }
  1526. cleanup:
  1527. FreeJBstr(lpszIndexName);
  1528. return IsSuccess();
  1529. }
  1530. //--------------------------------------------------------------------
  1531. BOOL
  1532. JBTable::CloseTable()
  1533. {
  1534. BOOL bSuccess;
  1535. if(m_JetTableId == JET_tableidNil)
  1536. return TRUE;
  1537. bSuccess = m_JetDatabase.CloseTable(
  1538. m_JetTableId
  1539. );
  1540. if(bSuccess == FALSE)
  1541. {
  1542. m_JetErr = m_JetDatabase.GetLastJetError();
  1543. }
  1544. //
  1545. // Force close on table.
  1546. //
  1547. m_JetTableId = JET_tableidNil;
  1548. if(m_JetColumns)
  1549. delete [] m_JetColumns;
  1550. m_JetColumns = NULL;
  1551. m_NumJetColumns = 0;
  1552. return bSuccess;
  1553. }
  1554. //--------------------------------------------------------------------
  1555. BOOL
  1556. JBTable::CreateOpenTable(
  1557. IN LPCTSTR pszTableName,
  1558. IN unsigned long lPage, // 0
  1559. IN unsigned long lDensity // 20
  1560. )
  1561. /*
  1562. */
  1563. {
  1564. if(m_JetTableId != JET_tableidNil)
  1565. {
  1566. SetLastJetError(JET_errInvalidParameter);
  1567. return FALSE;
  1568. }
  1569. DebugOutput(
  1570. _TEXT("Creating Table %s\n"),
  1571. pszTableName
  1572. );
  1573. m_JetTableId = m_JetDatabase.CreateJetTable(
  1574. pszTableName,
  1575. lPage,
  1576. lDensity
  1577. );
  1578. if(m_JetTableId == JET_tableidNil)
  1579. {
  1580. m_JetErr = m_JetDatabase.GetLastJetError();
  1581. }
  1582. return (m_JetTableId != JET_tableidNil);
  1583. }
  1584. //--------------------------------------------------------------------
  1585. BOOL
  1586. JBTable::OpenTable(
  1587. IN LPCTSTR pszTableName,
  1588. IN void* pvParam,
  1589. IN unsigned long cbParam,
  1590. IN JET_GRBIT grbit
  1591. )
  1592. /*
  1593. */
  1594. {
  1595. DebugOutput(
  1596. _TEXT("Opening table %s\n"),
  1597. pszTableName
  1598. );
  1599. JB_ASSERT(m_JetTableId == JET_tableidNil);
  1600. if(m_JetTableId != JET_tableidNil)
  1601. {
  1602. SetLastJetError(JET_errTableInUse);
  1603. return FALSE;
  1604. }
  1605. m_JetTableId = m_JetDatabase.OpenJetTable(
  1606. pszTableName,
  1607. pvParam,
  1608. cbParam,
  1609. grbit
  1610. );
  1611. if(m_JetTableId == JET_tableidNil)
  1612. {
  1613. m_JetErr = m_JetDatabase.GetLastJetError();
  1614. }
  1615. else
  1616. {
  1617. // load column info in the table
  1618. _tcscpy(m_szTableName, pszTableName);
  1619. if(LoadTableInfo() == FALSE)
  1620. {
  1621. // force a close on table
  1622. CloseTable();
  1623. }
  1624. }
  1625. DebugOutput(
  1626. _TEXT("Open table %s return code %d\n"),
  1627. pszTableName,
  1628. GetLastJetError()
  1629. );
  1630. return (m_JetTableId != JET_tableidNil);
  1631. }
  1632. //--------------------------------------------------------------------
  1633. JBTable*
  1634. JBTable::DuplicateCursor(
  1635. JET_GRBIT grbit /* 0 */
  1636. )
  1637. /*
  1638. */
  1639. {
  1640. JET_TABLEID tableid;
  1641. tableid = m_JetDatabase.DuplicateJetCursor(
  1642. m_JetTableId,
  1643. grbit
  1644. );
  1645. if(tableid == JET_tableidNil)
  1646. {
  1647. m_JetErr = m_JetDatabase.GetLastJetError();
  1648. }
  1649. return new JBTable(
  1650. m_JetDatabase,
  1651. GetTableName(),
  1652. tableid
  1653. );
  1654. }
  1655. //--------------------------------------------------------------------
  1656. JBTable&
  1657. JBTable::operator=(const JBTable& srcTable)
  1658. {
  1659. if(this == &srcTable)
  1660. return *this;
  1661. // database has to be the same
  1662. // verify database is consistent
  1663. _tcscpy(m_szTableName, srcTable.GetTableName());
  1664. m_JetTableId = m_JetDatabase.DuplicateJetCursor(
  1665. srcTable.GetJetTableID(),
  1666. 0
  1667. );
  1668. if(m_JetTableId == JET_tableidNil)
  1669. {
  1670. m_JetErr = m_JetDatabase.GetLastJetError();
  1671. }
  1672. return *this;
  1673. }
  1674. //--------------------------------------------------------------------
  1675. int
  1676. JBTable::AddColumn(
  1677. int numColumns,
  1678. PTLSJBColumn pColumnDef
  1679. )
  1680. /*
  1681. */
  1682. {
  1683. JET_COLUMNDEF column;
  1684. JET_COLUMNID jet_columnid;
  1685. for(int i=0; i < numColumns; i++)
  1686. {
  1687. memset(&column, 0, sizeof(column));
  1688. column.cbStruct = sizeof(JET_COLUMNDEF);
  1689. column.coltyp = (pColumnDef+i)->colType;
  1690. column.wCountry = (pColumnDef+i)->wCountry;
  1691. column.langid = (pColumnDef+i)->langid;
  1692. column.cp = (pColumnDef+i)->colCodePage;
  1693. column.cbMax = (pColumnDef+i)->cbMaxLength;
  1694. column.grbit = (pColumnDef+i)->jbGrbit;
  1695. jet_columnid = AddJetColumn(
  1696. (pColumnDef+i)->pszColumnName,
  1697. &column,
  1698. (pColumnDef+i)->pbDefValue,
  1699. (pColumnDef+i)->cbDefValue
  1700. );
  1701. if(jet_columnid == JET_NIL_COLUMN)
  1702. break;
  1703. }
  1704. // return which column cause trouble
  1705. return i;
  1706. }
  1707. //--------------------------------------------------------------------
  1708. int
  1709. JBTable::AddIndex(
  1710. int numIndex,
  1711. PTLSJBIndex pIndex
  1712. )
  1713. /*
  1714. */
  1715. {
  1716. unsigned long keylength;
  1717. for(int i=0; i < numIndex; i++)
  1718. {
  1719. if((pIndex+i)->cbKey == -1)
  1720. {
  1721. // calculate index key length
  1722. keylength = 2;
  1723. while((pIndex+i)->pszIndexKey[keylength-1] != _TEXT('\0') ||
  1724. (pIndex+i)->pszIndexKey[keylength-2] != _TEXT('\0'))
  1725. {
  1726. if(keylength >= TLS_JETBLUE_MAX_INDEXKEY_LENGTH)
  1727. {
  1728. SetLastJetError(JET_errInvalidParameter);
  1729. break;
  1730. }
  1731. keylength++;
  1732. }
  1733. }
  1734. else
  1735. {
  1736. keylength = (pIndex+i)->cbKey;
  1737. }
  1738. if(keylength >= TLS_JETBLUE_MAX_INDEXKEY_LENGTH)
  1739. {
  1740. SetLastJetError(JET_errInvalidParameter);
  1741. break;
  1742. }
  1743. if(AddJetIndex(
  1744. (pIndex+i)->pszIndexName,
  1745. (pIndex+i)->pszIndexKey,
  1746. keylength,
  1747. (pIndex+i)->jbGrbit,
  1748. (pIndex+i)->ulDensity
  1749. ) == FALSE)
  1750. {
  1751. break;
  1752. }
  1753. }
  1754. return (i >= numIndex) ? 0 : i;
  1755. }
  1756. //-------------------------------------------------------------
  1757. CLASS_PRIVATE BOOL
  1758. JBTable::LoadTableInfo()
  1759. /*
  1760. */
  1761. {
  1762. #if 1
  1763. LPSTR lpszTableName=NULL;
  1764. JET_COLUMNLIST columns;
  1765. unsigned long cbMax;
  1766. JET_RETINFO jetRetInfo;
  1767. char lpszColumnName[MAX_JETBLUE_NAME_LENGTH+1];
  1768. int NumChars;
  1769. unsigned long index;
  1770. SINGLE_JET_CALL;
  1771. if(ConvertWstrToJBstr(GetTableName(), &lpszTableName) == FALSE)
  1772. {
  1773. SetLastJetError(JET_errInvalidParameter);
  1774. goto cleanup;
  1775. }
  1776. memset(&columns, 0, sizeof(columns));
  1777. columns.cbStruct = sizeof(JET_COLUMNLIST);
  1778. cbMax = sizeof(JET_COLUMNLIST);
  1779. m_JetErr = JetGetColumnInfo(
  1780. GetJetSessionID(),
  1781. GetJetDatabaseID(),
  1782. lpszTableName,
  1783. NULL,
  1784. (PVOID)&columns,
  1785. cbMax,
  1786. 1 // retrieve column list
  1787. );
  1788. if(IsSuccess() == FALSE)
  1789. goto cleanup;
  1790. //
  1791. // Table has just been created
  1792. //
  1793. if(columns.cRecord == 0)
  1794. goto cleanup;
  1795. m_JetColumns = new JBColumn[columns.cRecord];
  1796. if(m_JetColumns == NULL)
  1797. {
  1798. SetLastJetError(JET_errOutOfMemory);
  1799. goto cleanup;
  1800. }
  1801. SetLastJetError(JET_errSuccess);
  1802. //
  1803. // TODO - use JBColumn class to retrieve value
  1804. //
  1805. m_NumJetColumns = columns.cRecord;
  1806. for(index=0;
  1807. index < columns.cRecord && IsSuccess() == TRUE;
  1808. index++)
  1809. {
  1810. m_JetColumns[index].AttachToTable(this);
  1811. if(m_JetColumns[index].LoadJetColumnInfoFromJet(&columns) == FALSE)
  1812. {
  1813. m_JetErr = m_JetColumns[index].GetLastJetError();
  1814. break;
  1815. }
  1816. m_JetErr = JetMove(
  1817. GetJetSessionID(),
  1818. columns.tableid,
  1819. JET_MoveNext,
  1820. 0
  1821. );
  1822. }
  1823. if(GetLastJetError() == JET_errNoCurrentRecord && index >= columns.cRecord)
  1824. {
  1825. // otherwise - got to be a JetBlue bug here.
  1826. SetLastJetError(JET_errSuccess);
  1827. }
  1828. //
  1829. //
  1830. //
  1831. cleanup:
  1832. FreeJBstr(lpszTableName);
  1833. if(IsSuccess() == FALSE && m_JetColumns)
  1834. {
  1835. delete [] m_JetColumns;
  1836. m_JetColumns = NULL;
  1837. m_NumJetColumns = 0;
  1838. }
  1839. return IsSuccess();
  1840. #else
  1841. LPSTR lpszTableName=NULL;
  1842. JET_COLUMNLIST columns;
  1843. unsigned long cbMax;
  1844. JET_RETINFO jetRetInfo;
  1845. unsigned long cbActual;
  1846. char lpszColumnName[MAX_JETBLUE_NAME_LENGTH+1];
  1847. int NumChars;
  1848. unsigned long index;
  1849. SINGLE_JET_CALL;
  1850. if(ConvertWstrToJBstr(GetTableName(), &lpszTableName) == FALSE)
  1851. {
  1852. SetLastJetError(JET_errInvalidParameter);
  1853. goto cleanup;
  1854. }
  1855. memset(&columns, 0, sizeof(columns));
  1856. columns.cbStruct = sizeof(JET_COLUMNLIST);
  1857. cbMax = sizeof(JET_COLUMNLIST);
  1858. m_JetErr = JetGetColumnInfo(
  1859. GetJetSessionID(),
  1860. GetJetDatabaseID(),
  1861. lpszTableName,
  1862. NULL,
  1863. (PVOID)&columns,
  1864. cbMax,
  1865. 1 // retrieve column list
  1866. );
  1867. if(IsSuccess() == FALSE)
  1868. goto cleanup;
  1869. //
  1870. // Table has just been created
  1871. //
  1872. if(columns.cRecord == 0)
  1873. goto cleanup;
  1874. // retrieve column name, column id, column type and column size
  1875. m_Columns = (PJetColumns) AllocateMemory(sizeof(JetColumns) * columns.cRecord);
  1876. if(m_Columns == NULL)
  1877. {
  1878. SetLastJetError(JET_errOutOfMemory);
  1879. goto cleanup;
  1880. }
  1881. SetLastJetError(JET_errSuccess);
  1882. //
  1883. // TODO - use JBColumn class to retrieve value
  1884. //
  1885. m_NumColumns = columns.cRecord;
  1886. for(index=0;
  1887. index < columns.cRecord && IsSuccess() == TRUE;
  1888. index++)
  1889. {
  1890. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1891. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1892. // retrieve column name
  1893. m_JetErr = JetRetrieveColumn(
  1894. GetJetSessionID(),
  1895. columns.tableid,
  1896. columns.columnidcolumnname,
  1897. lpszColumnName,
  1898. sizeof(lpszColumnName),
  1899. &cbActual,
  1900. 0,
  1901. &jetRetInfo
  1902. );
  1903. if(IsSuccess() == FALSE)
  1904. continue;
  1905. NumChars = MultiByteToWideChar(
  1906. GetACP(),
  1907. MB_PRECOMPOSED,
  1908. lpszColumnName,
  1909. cbActual,
  1910. (m_Columns+index)->pszColumnName,
  1911. sizeof((m_Columns+index)->pszColumnName)
  1912. );
  1913. if(NumChars == 0)
  1914. {
  1915. SetLastJetError(JET_errInvalidParameter);
  1916. continue;
  1917. }
  1918. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1919. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1920. // retrieve column ID
  1921. m_JetErr = JetRetrieveColumn(
  1922. GetJetSessionID(),
  1923. columns.tableid,
  1924. columns.columnidcolumnid,
  1925. &((m_Columns+index)->colId),
  1926. sizeof((m_Columns+index)->colId),
  1927. &cbActual,
  1928. 0,
  1929. &jetRetInfo
  1930. );
  1931. if(IsSuccess() == FALSE)
  1932. continue;
  1933. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1934. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1935. m_JetErr = JetRetrieveColumn(
  1936. GetJetSessionID(),
  1937. columns.tableid,
  1938. columns.columnidcoltyp,
  1939. &((m_Columns+index)->colType),
  1940. sizeof((m_Columns+index)->colType),
  1941. &cbActual,
  1942. 0,
  1943. &jetRetInfo
  1944. );
  1945. if(IsSuccess() == FALSE)
  1946. continue;
  1947. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1948. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1949. m_JetErr = JetRetrieveColumn(
  1950. GetJetSessionID(),
  1951. columns.tableid,
  1952. columns.columnidcbMax,
  1953. &((m_Columns+index)->cbMaxLength),
  1954. sizeof((m_Columns+index)->cbMaxLength),
  1955. &cbActual,
  1956. 0,
  1957. &jetRetInfo
  1958. );
  1959. if(IsSuccess() == FALSE)
  1960. continue;
  1961. memset(&jetRetInfo, 0, sizeof(JET_RETINFO));
  1962. jetRetInfo.cbStruct = sizeof(JET_RETINFO);
  1963. m_JetErr = JetRetrieveColumn(
  1964. GetJetSessionID(),
  1965. columns.tableid,
  1966. columns.columnidgrbit,
  1967. &((m_Columns+index)->jbGrbit),
  1968. sizeof((m_Columns+index)->jbGrbit),
  1969. &cbActual,
  1970. 0,
  1971. &jetRetInfo
  1972. );
  1973. DebugOutput(
  1974. _TEXT("Loaded Column name %s, Column Type %d, Column ID %d\n"),
  1975. m_Columns[index].pszColumnName,
  1976. m_Columns[index].colType,
  1977. m_Columns[index].colId
  1978. );
  1979. if(IsSuccess() == FALSE)
  1980. continue;
  1981. m_JetErr = JetMove(
  1982. GetJetSessionID(),
  1983. columns.tableid,
  1984. JET_MoveNext,
  1985. 0
  1986. );
  1987. }
  1988. if(GetLastJetError() == JET_errNoCurrentRecord && index >= columns.cRecord)
  1989. {
  1990. // otherwise - got to be a JetBlue bug here.
  1991. SetLastJetError(JET_errSuccess);
  1992. }
  1993. //
  1994. //
  1995. //
  1996. cleanup:
  1997. FreeJBstr(lpszTableName);
  1998. if(IsSuccess() == FALSE && m_Columns)
  1999. {
  2000. FreeMemory(m_Columns);
  2001. m_Columns = NULL;
  2002. m_NumColumns = 0;
  2003. }
  2004. return IsSuccess();
  2005. #endif
  2006. }
  2007. //-------------------------------------------------------------
  2008. JET_COLUMNID
  2009. JBTable::GetJetColumnID(
  2010. LPCTSTR pszColumnName
  2011. )
  2012. /*
  2013. */
  2014. {
  2015. int index;
  2016. index = GetJetColumnIndex(pszColumnName);
  2017. if(index < 0 || index >= m_NumJetColumns)
  2018. {
  2019. return (DWORD)JET_NIL_COLUMN;
  2020. }
  2021. return m_JetColumns[index].GetJetColumnID();
  2022. }
  2023. //-------------------------------------------------------------
  2024. int
  2025. JBTable::GetJetColumnIndex(
  2026. LPCTSTR pszColumnName
  2027. )
  2028. /*
  2029. */
  2030. {
  2031. if(m_JetColumns == NULL || m_NumJetColumns == 0)
  2032. {
  2033. SetLastJetError(JET_errNotInitialized);
  2034. return -1;
  2035. }
  2036. for(int index=0; index < m_NumJetColumns; index++)
  2037. {
  2038. if(_tcsicmp(m_JetColumns[index].GetJetColumnName(), pszColumnName) == 0)
  2039. break;
  2040. }
  2041. return (index >= m_NumJetColumns) ? -1 : index;
  2042. }
  2043. //-------------------------------------------------------------
  2044. JBColumn*
  2045. JBTable::FindColumnByIndex(
  2046. const int index
  2047. )
  2048. /*
  2049. */
  2050. {
  2051. if(m_JetColumns == NULL || m_NumJetColumns == 0)
  2052. {
  2053. SetLastJetError(JET_errNotInitialized);
  2054. return NULL;
  2055. }
  2056. if(index < 0 || index >= m_NumJetColumns)
  2057. {
  2058. SetLastJetError(JET_errInvalidParameter);
  2059. return NULL;
  2060. }
  2061. return m_JetColumns+index;
  2062. }
  2063. //--------------------------------------------------------------
  2064. JBColumn*
  2065. JBTable::FindColumnByColumnId(
  2066. const JET_COLUMNID JetColId
  2067. )
  2068. /*
  2069. */
  2070. {
  2071. if(m_JetColumns == NULL || m_NumJetColumns == 0)
  2072. {
  2073. SetLastJetError(JET_errNotInitialized);
  2074. return NULL;
  2075. }
  2076. for(int index=0; index < m_NumJetColumns; index++)
  2077. {
  2078. if(m_JetColumns[index].GetJetColumnID() == JetColId)
  2079. break;
  2080. }
  2081. return FindColumnByIndex( index );
  2082. }
  2083. //--------------------------------------------------------------
  2084. JBColumn*
  2085. JBTable::FindColumnByName(
  2086. LPCTSTR pszColumnName
  2087. )
  2088. /*
  2089. */
  2090. {
  2091. return FindColumnByIndex(GetJetColumnIndex(pszColumnName));
  2092. }
  2093. //--------------------------------------------------------------
  2094. BOOL
  2095. JBTable::BeginUpdate(
  2096. BOOL bUpdate /* false */
  2097. )
  2098. /*
  2099. */
  2100. {
  2101. if(GetTransactionLevel() == 0)
  2102. {
  2103. SetLastJetError(JET_errNotInTransaction);
  2104. JB_ASSERT(FALSE);
  2105. return FALSE;
  2106. }
  2107. SINGLE_JET_CALL;
  2108. m_JetErr = JetPrepareUpdate(
  2109. GetJetSessionID(),
  2110. GetJetTableID(),
  2111. (bUpdate) ? JET_prepReplace : JET_prepInsert
  2112. );
  2113. return IsSuccess();
  2114. }
  2115. //-------------------------------------------------------------
  2116. BOOL
  2117. JBTable::EndUpdate(
  2118. BOOL bDisacrd /* FALSE */
  2119. )
  2120. /*
  2121. */
  2122. {
  2123. BYTE pBookmark[JET_cbBookmarkMost+1];
  2124. DWORD cbActual = 0;
  2125. SINGLE_JET_CALL;
  2126. //
  2127. // Hack for work item table.
  2128. //
  2129. m_JetErr = JetUpdate(
  2130. GetJetSessionID(),
  2131. GetJetTableID(),
  2132. pBookmark,
  2133. JET_cbBookmarkMost,
  2134. &cbActual
  2135. );
  2136. if(IsSuccess() && m_InsertRepositionBookmark)
  2137. {
  2138. GotoBookmark(pBookmark, cbActual);
  2139. }
  2140. return IsSuccess();
  2141. }
  2142. //-------------------------------------------------------------
  2143. BOOL
  2144. JBTable::SetCurrentIndex(
  2145. LPCTSTR pszIndexName,
  2146. JET_GRBIT grbit /* JET_bitMoveFirst */
  2147. )
  2148. /*++
  2149. --*/
  2150. {
  2151. if(IsValid() == FALSE || m_InEnumeration == TRUE)
  2152. {
  2153. SetLastJetError(JET_errNotInitialized);
  2154. return FALSE;
  2155. }
  2156. //
  2157. // Can't be in enumeration and and try to set index
  2158. //
  2159. JB_ASSERT(m_InEnumeration == FALSE);
  2160. char* lpszIndexName=NULL;
  2161. if(ConvertWstrToJBstr(pszIndexName, &lpszIndexName) == FALSE)
  2162. {
  2163. SetLastJetError(JET_errInvalidParameter);
  2164. goto cleanup;
  2165. }
  2166. {
  2167. SINGLE_JET_CALL;
  2168. m_JetErr = JetSetCurrentIndex2(
  2169. GetJetSessionID(),
  2170. GetJetTableID(),
  2171. lpszIndexName,
  2172. grbit
  2173. );
  2174. }
  2175. if(IsSuccess())
  2176. {
  2177. m_InEnumeration = TRUE;
  2178. }
  2179. cleanup:
  2180. FreeJBstr(lpszIndexName);
  2181. return IsSuccess();
  2182. }
  2183. //-------------------------------------------------------------
  2184. BOOL
  2185. JBTable::EnumBegin(
  2186. LPCTSTR pszIndexName,
  2187. JET_GRBIT grbit /* JET_bitMoveFirst */
  2188. )
  2189. /*
  2190. */
  2191. {
  2192. if(m_InEnumeration == TRUE)
  2193. {
  2194. //
  2195. // Force terminate enumeration
  2196. //
  2197. EnumEnd();
  2198. }
  2199. return SetCurrentIndex(pszIndexName, grbit);
  2200. }
  2201. //-------------------------------------------------------------
  2202. JBTable::ENUM_RETCODE
  2203. JBTable::EnumNext(
  2204. JET_GRBIT crow /* JET_MoveNext */,
  2205. JET_GRBIT grbit /* 0 */
  2206. )
  2207. /*
  2208. */
  2209. {
  2210. if(m_InEnumeration == FALSE)
  2211. {
  2212. SetLastJetError(JET_errInvalidParameter);
  2213. return ENUM_ERROR;
  2214. }
  2215. if(IsValid() == FALSE)
  2216. {
  2217. SetLastJetError(JET_errNotInitialized);
  2218. return ENUM_ERROR;
  2219. }
  2220. ENUM_RETCODE retCode = ENUM_CONTINUE;
  2221. while( retCode == ENUM_CONTINUE )
  2222. {
  2223. MoveToRecord(crow, grbit);
  2224. switch(m_JetErr)
  2225. {
  2226. case JET_errSuccess:
  2227. retCode = ENUM_SUCCESS;
  2228. break;
  2229. case JET_errNoCurrentRecord:
  2230. retCode = ENUM_END;
  2231. break;
  2232. case JET_errRecordDeleted:
  2233. retCode = ENUM_CONTINUE;
  2234. break;
  2235. default:
  2236. retCode = ENUM_ERROR;
  2237. }
  2238. }
  2239. return retCode;
  2240. }
  2241. //-------------------------------------------------------------
  2242. BOOL
  2243. JBTable::SeekToKey(
  2244. JBKeyBase* key,
  2245. DWORD dwSeachParam,
  2246. JET_GRBIT jetseekgrbit /* =JET_bitSeekGE */
  2247. )
  2248. /*
  2249. */
  2250. {
  2251. if(IsValid() == FALSE)
  2252. {
  2253. SetLastJetError(JET_errNotInitialized);
  2254. return FALSE;
  2255. }
  2256. #ifdef DEBUG_SEEK
  2257. LPTSTR szKey=key->GetIndexKey();
  2258. #endif
  2259. EnumBegin(
  2260. key->GetIndexName(),
  2261. JET_bitMoveFirst
  2262. );
  2263. if(IsSuccess() == FALSE)
  2264. return FALSE;
  2265. if(key->IsEmptyValue() == TRUE)
  2266. {
  2267. return TRUE;
  2268. }
  2269. PVOID pbData;
  2270. unsigned long cbData;
  2271. JET_GRBIT key_grbit=JET_bitNewKey;
  2272. SetLastJetError(JET_errSuccess);
  2273. for(DWORD dwComponent=0;
  2274. dwComponent < key->GetNumKeyComponents();
  2275. dwComponent++)
  2276. {
  2277. if(key->GetSearchKey(dwComponent, &pbData, &cbData, &key_grbit, dwSeachParam) == FALSE)
  2278. break;
  2279. if(MakeKey(pbData, cbData, key_grbit) == FALSE)
  2280. break;
  2281. }
  2282. #ifdef DEBUG_SEEK
  2283. PVOID pb=NULL;
  2284. DWORD cb=0;
  2285. unsigned long actual;
  2286. SINGLE_JET_CALL;
  2287. m_JetErr = JetRetrieveKey(
  2288. GetJetSessionID(),
  2289. GetJetTableID(),
  2290. pb,
  2291. cb,
  2292. &actual,
  2293. 0
  2294. );
  2295. pb = (PVOID)AllocateMemory(actual);
  2296. cb = actual;
  2297. m_JetErr = JetRetrieveKey(
  2298. GetJetSessionID(),
  2299. GetJetTableID(),
  2300. pb,
  2301. cb,
  2302. &actual,
  2303. 0
  2304. );
  2305. FreeMemory(pb);
  2306. #endif
  2307. return IsSuccess() ? SeekValue(jetseekgrbit) : FALSE;
  2308. }
  2309. //-------------------------------------------------------------
  2310. BOOL
  2311. JBTable::EnumBegin(
  2312. JBKeyBase* key,
  2313. DWORD dwSearchParam
  2314. )
  2315. /*
  2316. */
  2317. {
  2318. if(IsValid() == FALSE)
  2319. {
  2320. SetLastJetError(JET_errNotInitialized);
  2321. return FALSE;
  2322. }
  2323. if(m_InEnumeration == TRUE)
  2324. {
  2325. // what do we do???
  2326. }
  2327. return SeekToKey(key, dwSearchParam);
  2328. }
  2329. //-------------------------------------------------------------
  2330. BOOL
  2331. JBTable::GetCurrentIndex(
  2332. LPTSTR pszIndexName,
  2333. unsigned long* bufferSize
  2334. )
  2335. /*
  2336. */
  2337. {
  2338. char lpszIndexName[MAX_JETBLUE_NAME_LENGTH+1];
  2339. int NumChars=0;
  2340. SINGLE_JET_CALL;
  2341. m_JetErr = JetGetCurrentIndex(
  2342. GetJetSessionID(),
  2343. GetJetTableID(),
  2344. lpszIndexName,
  2345. sizeof(lpszIndexName)
  2346. );
  2347. if(IsSuccess() == FALSE)
  2348. goto cleanup;
  2349. NumChars = MultiByteToWideChar(
  2350. GetACP(),
  2351. MB_PRECOMPOSED,
  2352. lpszIndexName,
  2353. -1,
  2354. pszIndexName,
  2355. *bufferSize
  2356. );
  2357. if(NumChars == 0)
  2358. {
  2359. SetLastJetError(JET_errInvalidParameter);
  2360. goto cleanup;
  2361. }
  2362. *bufferSize = NumChars;
  2363. cleanup:
  2364. return IsSuccess();
  2365. }
  2366. //-------------------------------------------------------------
  2367. BOOL
  2368. JBTable::GetBookmark(
  2369. PVOID pbBuffer,
  2370. PDWORD pcbBufSize
  2371. )
  2372. /*++
  2373. --*/
  2374. {
  2375. DWORD cbBufferSize = *pcbBufSize;
  2376. SINGLE_JET_CALL;
  2377. m_JetErr = JetGetBookmark(
  2378. GetJetSessionID(),
  2379. GetJetTableID(),
  2380. pbBuffer,
  2381. cbBufferSize,
  2382. pcbBufSize
  2383. );
  2384. if(m_JetErr == JET_errBufferTooSmall)
  2385. {
  2386. SetLastJetError(m_JetErr);
  2387. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  2388. }
  2389. return IsSuccess();
  2390. }
  2391. //-------------------------------------------------------------
  2392. BOOL
  2393. JBTable::GotoBookmark(
  2394. PVOID pbBuffer,
  2395. DWORD cbBuffer
  2396. )
  2397. /*++
  2398. --*/
  2399. {
  2400. SINGLE_JET_CALL;
  2401. m_JetErr = JetGotoBookmark(
  2402. GetJetSessionID(),
  2403. GetJetTableID(),
  2404. pbBuffer,
  2405. cbBuffer
  2406. );
  2407. return IsSuccess();
  2408. }
  2409. //-------------------------------------------------------------
  2410. BOOL
  2411. JBTable::ReadLock()
  2412. {
  2413. SINGLE_JET_CALL;
  2414. m_JetErr = JetGetLock(
  2415. GetJetSessionID(),
  2416. GetJetTableID(),
  2417. JET_bitReadLock
  2418. );
  2419. return IsSuccess();
  2420. }
  2421. //-------------------------------------------------------------
  2422. BOOL
  2423. JBTable::WriteLock()
  2424. {
  2425. SINGLE_JET_CALL;
  2426. m_JetErr = JetGetLock(
  2427. GetJetSessionID(),
  2428. GetJetTableID(),
  2429. JET_bitWriteLock
  2430. );
  2431. return IsSuccess();
  2432. }
  2433. //-------------------------------------------------------------
  2434. BOOL
  2435. JBTable::RetrieveKey(
  2436. PVOID pbData,
  2437. unsigned long cbData,
  2438. unsigned long* pcbActual,
  2439. JET_GRBIT grbit
  2440. )
  2441. /*
  2442. */
  2443. {
  2444. unsigned long cbActual;
  2445. SINGLE_JET_CALL;
  2446. m_JetErr = JetRetrieveKey(
  2447. GetJetSessionID(),
  2448. GetJetTableID(),
  2449. pbData,
  2450. cbData,
  2451. (pcbActual) ? pcbActual : &cbActual,
  2452. grbit // user2.doc - unuse.
  2453. );
  2454. return IsSuccess();
  2455. }
  2456. //-------------------------------------------------------------
  2457. BOOL
  2458. JBTable::MoveToRecord(
  2459. long crow,
  2460. JET_GRBIT grbit
  2461. )
  2462. /*
  2463. */
  2464. {
  2465. SINGLE_JET_CALL;
  2466. m_JetErr = JetMove(
  2467. GetJetSessionID(),
  2468. GetJetTableID(),
  2469. crow,
  2470. grbit
  2471. );
  2472. return IsSuccess();
  2473. }
  2474. //-------------------------------------------------------------
  2475. unsigned long
  2476. JBTable::GetIndexRecordCount(
  2477. unsigned long max
  2478. )
  2479. /*
  2480. */
  2481. {
  2482. unsigned long count;
  2483. SINGLE_JET_CALL;
  2484. m_JetErr = JetIndexRecordCount(
  2485. GetJetSessionID(),
  2486. GetJetTableID(),
  2487. &count,
  2488. max
  2489. );
  2490. return IsSuccess() ? count : 0;
  2491. }
  2492. //-------------------------------------------------------------
  2493. BOOL
  2494. JBTable::MakeKey(
  2495. PVOID pbData,
  2496. unsigned long cbData,
  2497. JET_GRBIT grbit
  2498. )
  2499. /*
  2500. */
  2501. {
  2502. SINGLE_JET_CALL;
  2503. m_JetErr = JetMakeKey(
  2504. GetJetSessionID(),
  2505. GetJetTableID(),
  2506. pbData,
  2507. cbData,
  2508. grbit
  2509. );
  2510. return IsSuccess();
  2511. }
  2512. //-------------------------------------------------------------
  2513. BOOL
  2514. JBTable::SeekValue(
  2515. JET_GRBIT grbit
  2516. )
  2517. /*
  2518. */
  2519. {
  2520. SINGLE_JET_CALL;
  2521. m_JetErr = JetSeek(
  2522. GetJetSessionID(),
  2523. GetJetTableID(),
  2524. grbit
  2525. );
  2526. return IsSuccess();
  2527. }
  2528. //-------------------------------------------------------------
  2529. BOOL
  2530. JBTable::DeleteRecord()
  2531. /*
  2532. */
  2533. {
  2534. SINGLE_JET_CALL;
  2535. // must have current record set
  2536. m_JetErr = JetDelete(
  2537. GetJetSessionID(),
  2538. GetJetTableID()
  2539. );
  2540. return IsSuccess();
  2541. }
  2542. //
  2543. //////////////////////////////////////////////////////////////
  2544. //
  2545. CLASS_PRIVATE void
  2546. JBColumn::Cleanup()
  2547. /*
  2548. */
  2549. {
  2550. memset(m_szColumnName, 0, sizeof(m_szColumnName));
  2551. }
  2552. //-----------------------------------------------------------
  2553. JBColumn::JBColumn(JBTable* pJetTable) :
  2554. m_pJetTable(pJetTable),
  2555. m_JetColId(0),
  2556. m_JetColType(JET_coltypNil),
  2557. m_JetMaxColLength(0),
  2558. m_JetGrbit(0),
  2559. m_JetColCodePage(TLS_JETBLUE_COLUMN_CODE_PAGE),
  2560. m_JetColCountryCode(TLS_JETBLUE_COLUMN_COUNTRY_CODE),
  2561. m_JetColLangId(TLS_JETBLUE_COLUMN_LANGID),
  2562. m_cbActual(0),
  2563. m_pbDefValue(NULL),
  2564. m_cbDefValue(0),
  2565. m_JetNullColumn(FALSE)
  2566. /*
  2567. */
  2568. {
  2569. Cleanup();
  2570. }
  2571. //-----------------------------------------------------------
  2572. CLASS_PRIVATE JET_ERR
  2573. JBColumn::RetrieveColumnValue(
  2574. IN JET_SESID sesid,
  2575. IN JET_TABLEID tableid,
  2576. IN JET_COLUMNID columnid,
  2577. IN OUT PVOID pbBuffer,
  2578. IN unsigned long cbBuffer,
  2579. IN unsigned long offset
  2580. )
  2581. /*
  2582. */
  2583. {
  2584. m_JetRetInfo.cbStruct = sizeof(m_JetRetInfo);
  2585. m_JetRetInfo.ibLongValue = offset;
  2586. m_JetNullColumn = FALSE;
  2587. m_cbActual = 0;
  2588. SINGLE_JET_CALL;
  2589. //
  2590. // JETBLUE bug??? passing zeror buffer size returns Column NULL
  2591. //
  2592. m_JetErr = JetRetrieveColumn(
  2593. sesid,
  2594. tableid,
  2595. columnid,
  2596. pbBuffer,
  2597. cbBuffer,
  2598. &m_cbActual,
  2599. 0,
  2600. NULL // &m_JetRetInfo
  2601. );
  2602. if(m_JetErr == JET_wrnColumnNull)
  2603. m_JetNullColumn = TRUE;
  2604. return IsSuccess();
  2605. }
  2606. //-----------------------------------------------------------
  2607. CLASS_PRIVATE BOOL
  2608. JBColumn::LoadJetColumnInfoFromJet(
  2609. const JET_COLUMNLIST* pColumnList
  2610. )
  2611. /*
  2612. */
  2613. {
  2614. char lpszColumnName[MAX_JETBLUE_NAME_LENGTH+1];
  2615. int NumChars;
  2616. //
  2617. // retrieve column name
  2618. //
  2619. RetrieveColumnValue(
  2620. GetJetSessionID(),
  2621. pColumnList->tableid,
  2622. pColumnList->columnidcolumnname,
  2623. lpszColumnName,
  2624. sizeof(lpszColumnName)
  2625. );
  2626. if(IsSuccess() == FALSE)
  2627. goto cleanup;
  2628. NumChars = MultiByteToWideChar(
  2629. GetACP(),
  2630. MB_PRECOMPOSED,
  2631. lpszColumnName,
  2632. m_cbActual,
  2633. m_szColumnName,
  2634. sizeof(m_szColumnName)/sizeof(m_szColumnName[0])
  2635. );
  2636. if(NumChars == 0)
  2637. {
  2638. SetLastJetError(JET_errInvalidParameter);
  2639. goto cleanup;
  2640. }
  2641. //DebugOutput(
  2642. // _TEXT("Load column %s"),
  2643. // m_szColumnName
  2644. // );
  2645. //
  2646. // retrieve column ID
  2647. //
  2648. RetrieveColumnValue(
  2649. GetJetSessionID(),
  2650. pColumnList->tableid,
  2651. pColumnList->columnidcolumnid,
  2652. &m_JetColId,
  2653. sizeof(m_JetColId)
  2654. );
  2655. if(IsSuccess() == FALSE)
  2656. goto cleanup;
  2657. //DebugOutput(
  2658. // _TEXT("\tColId - %d"),
  2659. // m_JetColId
  2660. // );
  2661. //
  2662. // Retrieve Column Type
  2663. //
  2664. RetrieveColumnValue(
  2665. GetJetSessionID(),
  2666. pColumnList->tableid,
  2667. pColumnList->columnidcoltyp,
  2668. &m_JetColType,
  2669. sizeof(m_JetColType)
  2670. );
  2671. if(IsSuccess() == FALSE)
  2672. goto cleanup;
  2673. //DebugOutput(
  2674. // _TEXT("\tCol Type %d"),
  2675. // m_JetColType
  2676. // );
  2677. //
  2678. // Retrieve Max. length for LongText and Long Binary
  2679. //
  2680. RetrieveColumnValue(
  2681. GetJetSessionID(),
  2682. pColumnList->tableid,
  2683. pColumnList->columnidcbMax,
  2684. &m_JetMaxColLength,
  2685. sizeof(m_JetMaxColLength)
  2686. );
  2687. if(IsSuccess() == FALSE)
  2688. goto cleanup;
  2689. //DebugOutput(
  2690. // _TEXT("\tMax Col Length %d"),
  2691. // m_JetMaxColLength
  2692. // );
  2693. //
  2694. // Retrieve Column Grbit
  2695. //
  2696. RetrieveColumnValue(
  2697. GetJetSessionID(),
  2698. pColumnList->tableid,
  2699. pColumnList->columnidgrbit,
  2700. &m_JetGrbit,
  2701. sizeof(m_JetGrbit)
  2702. );
  2703. if(IsSuccess() == FALSE)
  2704. goto cleanup;
  2705. //DebugOutput(
  2706. // _TEXT("\tCol grbit %d"),
  2707. // m_JetGrbit
  2708. // );
  2709. cleanup:
  2710. //DebugOutput(
  2711. // _TEXT("\n")
  2712. // );
  2713. return IsSuccess();
  2714. }
  2715. //-----------------------------------------------------------
  2716. BOOL
  2717. JBColumn::IsValid() const
  2718. /*
  2719. */
  2720. {
  2721. return m_pJetTable != NULL && m_pJetTable->IsValid();
  2722. }
  2723. //-----------------------------------------------------------
  2724. BOOL
  2725. JBColumn::InsertColumn(
  2726. PVOID pbData,
  2727. unsigned long cbData,
  2728. unsigned long offset
  2729. )
  2730. /*
  2731. */
  2732. {
  2733. //JET_SETINFO setinfo;
  2734. if(IsValid() == FALSE)
  2735. {
  2736. SetLastJetError(JET_errInvalidParameter);
  2737. return IsSuccess();
  2738. }
  2739. SINGLE_JET_CALL;
  2740. // if(GetJetColumnType() == JET_coltypLongText || GetJetColumnType() == JET_coltypLongBinary)
  2741. if(pbData == NULL || cbData == 0)
  2742. {
  2743. m_JetErr = JetSetColumn(
  2744. GetJetSessionID(),
  2745. GetJetTableID(),
  2746. GetJetColumnID(),
  2747. 0,
  2748. 0,
  2749. JET_bitSetZeroLength,
  2750. NULL
  2751. );
  2752. if(IsSuccess() == FALSE)
  2753. return FALSE;
  2754. m_JetErr = JetSetColumn(
  2755. GetJetSessionID(),
  2756. GetJetTableID(),
  2757. GetJetColumnID(),
  2758. 0,
  2759. 0,
  2760. 0,
  2761. NULL
  2762. );
  2763. if(IsSuccess() == FALSE)
  2764. return FALSE;
  2765. }
  2766. m_JetErr = JetSetColumn(
  2767. GetJetSessionID(),
  2768. GetJetTableID(),
  2769. GetJetColumnID(),
  2770. pbData,
  2771. cbData,
  2772. 0,
  2773. NULL
  2774. );
  2775. return IsSuccess();
  2776. }
  2777. //-----------------------------------------------------------
  2778. BOOL
  2779. JBColumn::FetchColumn(
  2780. PVOID pbData,
  2781. unsigned long cbData,
  2782. unsigned long starting_offset
  2783. )
  2784. /*
  2785. pass NULL and 0 to determine buffer size needed.
  2786. */
  2787. {
  2788. if(IsValid() == FALSE)
  2789. {
  2790. SetLastJetError(JET_errNotInitialized);
  2791. }
  2792. else
  2793. {
  2794. RetrieveColumnValue(
  2795. GetJetSessionID(),
  2796. GetJetTableID(),
  2797. GetJetColumnID(),
  2798. pbData,
  2799. cbData,
  2800. starting_offset
  2801. );
  2802. }
  2803. return IsSuccess();
  2804. }