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.

1610 lines
37 KiB

  1. // GuideDB.cpp : Implementation of CGuideDB
  2. #include "stdafx.h"
  3. #include "GuideDB.h"
  4. #include "object.h"
  5. #include "GuideDataProvider.h"
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CGuideDB
  8. const TCHAR *g_szConnection =
  9. _T("Provider=Microsoft.Jet.OLEDB.4.0;")
  10. _T("Data Source=\"%s\";")
  11. _T("Password=\"\";")
  12. _T("User ID=Admin;")
  13. _T("Mode=Share Deny None;")
  14. _T("Extended Properties=\"\";")
  15. _T("Jet OLEDB:System database=\"\";")
  16. _T("Jet OLEDB:Registry Path=\"\";")
  17. _T("Jet OLEDB:Database Password=\"\";")
  18. _T("Jet OLEDB:Engine Type=5;")
  19. _T("Jet OLEDB:Database Locking Mode=1;")
  20. _T("Jet OLEDB:Global Partial Bulk Ops=2;")
  21. _T("Jet OLEDB:Global Bulk Transactions=1;")
  22. _T("Jet OLEDB:New Database Password=\"\";")
  23. _T("Jet OLEDB:Create System Database=False;")
  24. _T("Jet OLEDB:Encrypt Database=False;")
  25. _T("Jet OLEDB:Don't Copy Locale on Compact=False;")
  26. _T("Jet OLEDB:Compact Without Replica Repair=False;")
  27. _T("Jet OLEDB:SFP=False")
  28. ;
  29. const TCHAR *g_szConnectionSQL =
  30. _T("Provider=SQLOLEDB;")
  31. // _T("DRIVER=SQL Server;")
  32. // _T("UID=leeac;")
  33. _T("SERVER=(local);")
  34. _T("DATABASE=%s;")
  35. _T("Trusted_Connection=Yes;")
  36. // _T("WSID=LEEAC;")
  37. // _T("APP=Microsoft Open Database Connectivity;")
  38. ;
  39. const _bstr_t g_bstrDBUser(_T("Admin"));
  40. const _bstr_t g_bstrDBPassword(_T(""));
  41. const _variant_t g_varPropertySets(_T("PropertySets"));
  42. const _variant_t g_varStrings(_T("Strings"));
  43. const _variant_t g_varPropertyTypes(_T("PropertyTypes"));
  44. const _variant_t g_varProperties(_T("Properties"));
  45. const _variant_t g_varObjectTypes(_T("ObjectTypes"));
  46. const _variant_t g_varObjects(_T("Objects"));
  47. const _bstr_t g_bstrIDType(_T("idType"));
  48. const _variant_t g_varObjectRelationships(_T("ObjectRelationships"));
  49. const _bstr_t g_bstrIDObj1(_T("idObj1"));
  50. const _bstr_t g_bstrIDObj2(_T("idObj2"));
  51. const _bstr_t g_bstrIDObj1Rel(_T("idObj1Rel"));
  52. const _bstr_t g_bstrIDObj2Rel(_T("idObj2Rel"));
  53. const _bstr_t g_bstrValue(_T("Value"));
  54. class ColumnDesc
  55. {
  56. public:
  57. const TCHAR *m_szName;
  58. ADOX::DataTypeEnum m_type;
  59. long m_size;
  60. bool m_fAutoIncrement;
  61. bool m_fAllowNulls;
  62. };
  63. class IndexDesc
  64. {
  65. public:
  66. const TCHAR *m_szName;
  67. boolean m_fUnique;
  68. int m_cColumns;
  69. ColumnDesc **m_rgpcolumndesc;
  70. };
  71. #define IndexDescInit(b, n, fUnique) {_T(#n), fUnique, sizeofarray(g_rgpcolumndesc##b##_##n), g_rgpcolumndesc##b##_##n}
  72. #define PrimaryKeyInit(b, n) {_T("PK_") _T(#b), TRUE, sizeofarray(g_rgpcolumndesc##b##_##n), g_rgpcolumndesc##b##_##n}
  73. class TableDesc
  74. {
  75. public:
  76. const TCHAR *m_szName;
  77. IndexDesc *m_pindexdescPrimary;
  78. ColumnDesc *m_rgcolumndesc;
  79. IndexDesc *m_rgindexdesc;
  80. };
  81. #define TableDescInit(n) \
  82. {_T(#n), &g_indexdescPrimaryKey##n, g_rgcolumndesc##n, g_rgindexdesc##n}
  83. #define TableDescInit_NoPrimaryKey(n) \
  84. {_T(#n), NULL, g_rgcolumndesc##n, g_rgindexdesc##n}
  85. ColumnDesc g_rgcolumndescObjectTypes[] =
  86. {
  87. {_T("id"), ADOX::adInteger, 0, TRUE, FALSE},
  88. {_T("clsid"), ADOX::adVarWChar, 255, FALSE, FALSE},
  89. {NULL}
  90. };
  91. ColumnDesc *g_rgpcolumndescObjectTypes_id[] =
  92. {
  93. g_rgcolumndescObjectTypes + 0,
  94. };
  95. ColumnDesc *g_rgpcolumndescObjectTypes_clsid[] =
  96. {
  97. g_rgcolumndescObjectTypes + 1,
  98. };
  99. IndexDesc g_indexdescPrimaryKeyObjectTypes =
  100. PrimaryKeyInit(ObjectTypes, id);
  101. IndexDesc g_rgindexdescObjectTypes[] =
  102. {
  103. IndexDescInit(ObjectTypes, clsid, TRUE),
  104. {NULL}
  105. };
  106. ColumnDesc g_rgcolumndescObjects[] =
  107. {
  108. {_T("id"), ADOX::adInteger, 0, TRUE, FALSE},
  109. {_T("idtype"), ADOX::adInteger, 0, FALSE, FALSE},
  110. {_T("oValue"), ADOX::adLongVarBinary, 0, FALSE, TRUE},
  111. {NULL}
  112. };
  113. ColumnDesc *g_rgpcolumndescObjects_id[] =
  114. {
  115. g_rgcolumndescObjects + 0,
  116. };
  117. ColumnDesc *g_rgpcolumndescObjects_idType[] =
  118. {
  119. g_rgcolumndescObjects + 1,
  120. };
  121. IndexDesc g_indexdescPrimaryKeyObjects =
  122. PrimaryKeyInit(Objects, id);
  123. IndexDesc g_rgindexdescObjects[] =
  124. {
  125. IndexDescInit(Objects, idType, FALSE),
  126. {NULL}
  127. };
  128. ColumnDesc g_rgcolumndescObjectRelationships[] =
  129. {
  130. {_T("idObj1"), ADOX::adInteger, 0, FALSE, FALSE},
  131. {_T("idRel"), ADOX::adInteger, 0, FALSE, FALSE},
  132. {_T("order"), ADOX::adInteger, 0, FALSE, FALSE},
  133. {_T("idObj2"), ADOX::adInteger, 0, FALSE, FALSE},
  134. {NULL}
  135. };
  136. ColumnDesc *g_rgpcolumndescObjectRelationships_idObj1Rel[] =
  137. {
  138. g_rgcolumndescObjectRelationships + 0,
  139. g_rgcolumndescObjectRelationships + 1,
  140. g_rgcolumndescObjectRelationships + 2,
  141. };
  142. ColumnDesc *g_rgpcolumndescObjectRelationships_idObj2Rel[] =
  143. {
  144. g_rgcolumndescObjectRelationships + 3,
  145. g_rgcolumndescObjectRelationships + 1,
  146. g_rgcolumndescObjectRelationships + 2,
  147. };
  148. IndexDesc g_rgindexdescObjectRelationships[] =
  149. {
  150. IndexDescInit(ObjectRelationships, idObj1Rel, FALSE),
  151. IndexDescInit(ObjectRelationships, idObj2Rel, FALSE),
  152. {NULL}
  153. };
  154. ColumnDesc g_rgcolumndescPropertySets[] =
  155. {
  156. {_T("id"), ADOX::adInteger, 0, TRUE, FALSE},
  157. {_T("Name"), ADOX::adVarWChar, 255, FALSE, FALSE},
  158. {NULL}
  159. };
  160. ColumnDesc *g_rgpcolumndescPropertySets_id[] =
  161. {
  162. g_rgcolumndescPropertySets + 0,
  163. };
  164. ColumnDesc *g_rgpcolumndescPropertySets_Name[] =
  165. {
  166. g_rgcolumndescPropertySets + 1,
  167. };
  168. IndexDesc g_indexdescPrimaryKeyPropertySets =
  169. PrimaryKeyInit(PropertySets, id);
  170. IndexDesc g_rgindexdescPropertySets[] =
  171. {
  172. IndexDescInit(PropertySets, Name, TRUE),
  173. {NULL}
  174. };
  175. ColumnDesc g_rgcolumndescPropertyTypes[] =
  176. {
  177. {_T("id"), ADOX::adInteger, 0, TRUE, FALSE},
  178. {_T("idPropSet"), ADOX::adInteger, 0, FALSE, FALSE},
  179. {_T("idProp"), ADOX::adInteger, 0, FALSE, FALSE},
  180. {_T("Name"), ADOX::adVarWChar, 255, FALSE, FALSE},
  181. {NULL}
  182. };
  183. ColumnDesc *g_rgpcolumndescPropertyTypes_id[] =
  184. {
  185. g_rgcolumndescPropertyTypes + 0,
  186. };
  187. ColumnDesc *g_rgpcolumndescPropertyTypes_idPropSet[] =
  188. {
  189. g_rgcolumndescPropertyTypes + 1,
  190. };
  191. ColumnDesc *g_rgpcolumndescPropertyTypes_idPropSetidProp[] =
  192. {
  193. g_rgcolumndescPropertyTypes + 1,
  194. g_rgcolumndescPropertyTypes + 2,
  195. };
  196. ColumnDesc *g_rgpcolumndescPropertyTypes_idPropSetName[] =
  197. {
  198. g_rgcolumndescPropertyTypes + 1,
  199. g_rgcolumndescPropertyTypes + 3,
  200. };
  201. IndexDesc g_indexdescPrimaryKeyPropertyTypes =
  202. PrimaryKeyInit(PropertyTypes, id);
  203. IndexDesc g_rgindexdescPropertyTypes[] =
  204. {
  205. IndexDescInit(PropertyTypes, idPropSet, FALSE),
  206. IndexDescInit(PropertyTypes, idPropSetidProp, FALSE),
  207. IndexDescInit(PropertyTypes, idPropSetName, TRUE),
  208. {NULL}
  209. };
  210. ColumnDesc g_rgcolumndescProperties[] =
  211. {
  212. {_T("idObj"), ADOX::adInteger, 0, FALSE, FALSE},
  213. {_T("idPropType"), ADOX::adInteger, 0, FALSE, FALSE},
  214. {_T("idProvider"), ADOX::adInteger, 0, FALSE, FALSE},
  215. {_T("idLanguage"), ADOX::adInteger, 0, FALSE, FALSE},
  216. {_T("ValueType"), ADOX::adInteger, 0, FALSE, FALSE},
  217. {_T("lValue"), ADOX::adInteger, 0, FALSE, TRUE},
  218. {_T("sValue"), ADOX::adLongVarWChar, 0, FALSE, TRUE},
  219. {_T("fValue"), ADOX::adDouble, 0, FALSE, TRUE},
  220. {NULL}
  221. };
  222. ColumnDesc *g_rgpcolumndescProperties_PrimaryKey[] =
  223. {
  224. g_rgcolumndescProperties + 0,
  225. g_rgcolumndescProperties + 1,
  226. g_rgcolumndescProperties + 2,
  227. g_rgcolumndescProperties + 3,
  228. };
  229. IndexDesc g_indexdescPrimaryKeyProperties =
  230. PrimaryKeyInit(Properties, PrimaryKey);
  231. IndexDesc g_rgindexdescProperties[] =
  232. {
  233. {NULL}
  234. };
  235. ColumnDesc g_rgcolumndescStrings[] =
  236. {
  237. {_T("id"), ADOX::adInteger, 0, TRUE, FALSE},
  238. {_T("Value"), ADOX::adVarWChar, 255, FALSE, FALSE},
  239. {NULL}
  240. };
  241. ColumnDesc *g_rgpcolumndescStrings_PrimaryKey[] =
  242. {
  243. g_rgcolumndescStrings + 0,
  244. };
  245. IndexDesc g_indexdescPrimaryKeyStrings =
  246. PrimaryKeyInit(Strings, PrimaryKey);
  247. ColumnDesc *g_rgpcolumndescStrings_Value[] =
  248. {
  249. g_rgcolumndescStrings + 1,
  250. };
  251. IndexDesc g_rgindexdescStrings[] =
  252. {
  253. IndexDescInit(Strings, Value, FALSE),
  254. {NULL}
  255. };
  256. TableDesc g_rgtabledesc[] =
  257. {
  258. TableDescInit(ObjectTypes),
  259. TableDescInit(Objects),
  260. TableDescInit_NoPrimaryKey(ObjectRelationships),
  261. TableDescInit(PropertySets),
  262. TableDescInit(PropertyTypes),
  263. TableDescInit(Properties),
  264. TableDescInit(Strings),
  265. {NULL}
  266. };
  267. HRESULT CGuideDB::CreateDB(const TCHAR *szDBName, const TCHAR *szDBFileName,
  268. const TCHAR *szConnection)
  269. {
  270. if (m_fSQLServer)
  271. return CreateSQLDB(szDBName, szDBFileName, szConnection);
  272. HRESULT hr;
  273. ADOX::_CatalogPtr pcatalog;
  274. hr = pcatalog.CreateInstance(__uuidof(ADOX::Catalog));
  275. if (FAILED(hr))
  276. return hr;
  277. _variant_t varConnection;
  278. hr = pcatalog->Create(_bstr_t(szConnection), &varConnection);
  279. if (FAILED(hr))
  280. return hr;
  281. return InitDB(pcatalog);
  282. }
  283. HRESULT CGuideDB::CreateSQLDB(const TCHAR *szDBName, const TCHAR *szDBFileName,
  284. const TCHAR *szConnection)
  285. {
  286. HRESULT hr = E_FAIL;
  287. SQLDMO::_SQLServerPtr pSQLServer;
  288. hr = pSQLServer.CreateInstance(__uuidof(SQLDMO::SQLServer));
  289. if (FAILED(hr))
  290. return hr;
  291. hr = pSQLServer->put_LoginTimeout(10);
  292. if (FAILED(hr))
  293. return hr;
  294. hr = pSQLServer->put_LoginSecure(TRUE);
  295. if (FAILED(hr))
  296. return hr;
  297. hr = pSQLServer->put_ApplicationName(_bstr_t(_T("GuideStore")));
  298. if (FAILED(hr))
  299. return hr;
  300. hr = pSQLServer->Connect(_variant_t(_T(".")), _variant_t(_T("")), _variant_t(_T("")));
  301. if (FAILED(hr))
  302. return hr;
  303. SQLDMO::DatabasesPtr pdbs;
  304. hr = pSQLServer->get_Databases(&pdbs);
  305. SQLDMO::_DatabasePtr pdb;
  306. hr = pdb.CreateInstance(__uuidof(SQLDMO::Database));
  307. hr = pdb->put_Name(_bstr_t(szDBName));
  308. SQLDMO::_DBFilePtr pdbfile;
  309. hr = pdbfile.CreateInstance(__uuidof(SQLDMO::DBFile));
  310. hr = pdbfile->put_PhysicalName(_bstr_t(szDBFileName));
  311. hr = pdbfile->put_Name(_bstr_t(szDBName));
  312. hr = pdbfile->put_PrimaryFile(TRUE);
  313. SQLDMO::FileGroupsPtr pfilegroups;
  314. SQLDMO::_FileGroupPtr pfilegroup;
  315. SQLDMO::DBFilesPtr pdbfiles;
  316. hr = pdb->get_FileGroups(&pfilegroups);
  317. hr = pfilegroups->Item(_variant_t(_T("PRIMARY")), &pfilegroup);
  318. hr = pfilegroup->get_DBFiles(&pdbfiles);
  319. hr = pdbfiles->Add(pdbfile);
  320. hr = pdbs->Add(pdb);
  321. return InitSQLDB(pdb);
  322. }
  323. HRESULT CGuideDB::InitSQLDB(SQLDMO::_Database *pdb)
  324. {
  325. HRESULT hr;
  326. SQLDMO::TablesPtr ptables;
  327. hr = pdb->get_Tables(&ptables);
  328. if (FAILED(hr))
  329. return hr;
  330. for (TableDesc *ptabledesc = g_rgtabledesc; ptabledesc->m_szName != NULL; ptabledesc++)
  331. {
  332. _bstr_t bstrTableName(ptabledesc->m_szName);
  333. SQLDMO::_TablePtr ptable;
  334. hr = ptable.CreateInstance(__uuidof(SQLDMO::Table));
  335. if (FAILED(hr))
  336. return hr;
  337. hr = ptable->put_Name(bstrTableName);
  338. if (FAILED(hr))
  339. return hr;
  340. SQLDMO::ColumnsPtr pcols;
  341. hr = ptable->get_Columns(&pcols);
  342. if (FAILED(hr))
  343. return hr;
  344. ColumnDesc *pcolumndesc;
  345. for (pcolumndesc = ptabledesc->m_rgcolumndesc;
  346. pcolumndesc->m_szName != NULL; pcolumndesc++)
  347. {
  348. _bstr_t bstrColumnName(pcolumndesc->m_szName);
  349. _variant_t varColumnName(bstrColumnName);
  350. SQLDMO::_ColumnPtr pcol;
  351. hr = pcol.CreateInstance(__uuidof(SQLDMO::Column));
  352. if (FAILED(hr))
  353. return hr;
  354. hr = pcol->put_Name(bstrColumnName);
  355. _bstr_t bstrType;
  356. switch (pcolumndesc->m_type)
  357. {
  358. default:
  359. _ASSERTE(0);
  360. break;
  361. case ADOX::adInteger:
  362. bstrType = "integer";
  363. break;
  364. case ADOX::adLongVarWChar:
  365. bstrType = "text";
  366. if (pcolumndesc->m_size != 0)
  367. hr = pcol->put_Length(pcolumndesc->m_size);
  368. break;
  369. case ADOX::adVarWChar:
  370. bstrType = "varchar";
  371. hr = pcol->put_Length(pcolumndesc->m_size);
  372. break;
  373. case ADOX::adDouble:
  374. bstrType = "float";
  375. break;
  376. case ADOX::adLongVarBinary:
  377. bstrType = "image";
  378. long size = pcolumndesc->m_size;
  379. if (size == 0)
  380. size = 8000;
  381. hr = pcol->put_Length(size);
  382. break;
  383. }
  384. hr = pcol->put_Datatype(bstrType);
  385. if (pcolumndesc->m_fAutoIncrement)
  386. {
  387. hr = pcol->put_Identity((VARIANT_BOOL) -1);
  388. }
  389. if (pcolumndesc->m_fAllowNulls)
  390. {
  391. hr = pcol->put_AllowNulls((VARIANT_BOOL) -1);
  392. }
  393. hr = pcols->Add(pcol);
  394. }
  395. hr = ptables->Add(ptable);
  396. if (ptabledesc->m_rgindexdesc != NULL)
  397. {
  398. SQLDMO::IndexesPtr pindexes;
  399. hr = ptable->get_Indexes(&pindexes);
  400. for (IndexDesc *pindexdesc = ptabledesc->m_rgindexdesc;
  401. pindexdesc->m_szName != NULL; pindexdesc++)
  402. {
  403. _bstr_t bstrIndexName(pindexdesc->m_szName);
  404. int cColumns = pindexdesc->m_cColumns;
  405. _ASSERTE(cColumns > 0);
  406. SQLDMO::_IndexPtr pindex;
  407. hr = pindex.CreateInstance(__uuidof(SQLDMO::Index));
  408. _ASSERTE(SUCCEEDED(hr));
  409. hr = pindex->put_Name(bstrIndexName);
  410. _ASSERTE(SUCCEEDED(hr));
  411. _bstr_t bstrColumns;
  412. ColumnDesc **ppcolumndesc = pindexdesc->m_rgpcolumndesc;
  413. bstrColumns = _bstr_t((*ppcolumndesc++)->m_szName);
  414. for (long iColumn = 1; iColumn < cColumns; iColumn++, ppcolumndesc++)
  415. {
  416. bstrColumns += _bstr_t(" ") + (*ppcolumndesc)->m_szName;
  417. }
  418. hr = pindex->put_IndexedColumns(bstrColumns);
  419. SQLDMO::SQLDMO_INDEX_TYPE lType = SQLDMO::SQLDMOIndex_Default;
  420. if (pindexdesc->m_fUnique)
  421. lType = (SQLDMO::SQLDMO_INDEX_TYPE)(lType | SQLDMO::SQLDMOIndex_Unique);
  422. hr = pindex->put_Type(lType);
  423. hr = pindexes->Add(pindex);
  424. _ASSERTE(SUCCEEDED(hr));
  425. }
  426. }
  427. if (ptabledesc->m_pindexdescPrimary != NULL)
  428. {
  429. IndexDesc *pindexdesc = ptabledesc->m_pindexdescPrimary;
  430. SQLDMO::KeysPtr pkeys;
  431. hr = ptable->get_Keys(&pkeys);
  432. SQLDMO::_KeyPtr pkey;
  433. hr = pkey.CreateInstance(__uuidof(SQLDMO::Key));
  434. hr = pkey->put_Name(_bstr_t(pindexdesc->m_szName));
  435. hr = pkey->put_Type(SQLDMO::SQLDMOKey_Primary);
  436. SQLDMO::NamesPtr pnames;
  437. hr = pkey->get_KeyColumns(&pnames);
  438. int cColumns = pindexdesc->m_cColumns;
  439. _ASSERTE(cColumns > 0);
  440. ColumnDesc **ppcolumndesc = pindexdesc->m_rgpcolumndesc;
  441. for (long iColumn = 0; iColumn < cColumns; iColumn++, ppcolumndesc++)
  442. {
  443. _bstr_t bstrColumnName((*ppcolumndesc)->m_szName);
  444. hr = pnames->Add(bstrColumnName);
  445. }
  446. hr = pkeys->Add(pkey);
  447. }
  448. }
  449. return S_OK;
  450. }
  451. HRESULT AddIndex(ADOX::Indexes *pindexes, IndexDesc *pindexdesc, boolean fPrimary)
  452. {
  453. HRESULT hr;
  454. _bstr_t bstrIndexName(pindexdesc->m_szName);
  455. int cColumns = pindexdesc->m_cColumns;
  456. _ASSERTE(cColumns > 0);
  457. ADOX::_IndexPtr pindex;
  458. hr = pindex.CreateInstance(__uuidof(ADOX::Index));
  459. _ASSERTE(SUCCEEDED(hr));
  460. hr = pindex->put_Name(bstrIndexName);
  461. _ASSERTE(SUCCEEDED(hr));
  462. if (pindexdesc->m_fUnique)
  463. {
  464. if (fPrimary)
  465. {
  466. hr = pindex->put_PrimaryKey(-1);
  467. _ASSERTE(SUCCEEDED(hr));
  468. }
  469. else
  470. {
  471. hr = pindex->put_Unique(-1);
  472. _ASSERTE(SUCCEEDED(hr));
  473. }
  474. }
  475. ADOX::ColumnsPtr pcols;
  476. hr = pindex->get_Columns(&pcols);
  477. _ASSERTE(SUCCEEDED(hr));
  478. ColumnDesc **ppcolumndesc = pindexdesc->m_rgpcolumndesc;
  479. for (long iColumn = 0; iColumn < cColumns; iColumn++, ppcolumndesc++)
  480. {
  481. ColumnDesc *pcolumndesc = *ppcolumndesc;
  482. _variant_t varColumnName((*ppcolumndesc)->m_szName);
  483. hr = pcols->Append(varColumnName, pcolumndesc->m_type, pcolumndesc->m_size);
  484. _ASSERTE(SUCCEEDED(hr));
  485. }
  486. _variant_t varIndex((IDispatch*) pindex);
  487. hr = pindexes->Append(varIndex);
  488. _ASSERTE(SUCCEEDED(hr));
  489. return hr;
  490. }
  491. HRESULT CGuideDB::InitDB(ADOX::_Catalog *pcatalog)
  492. {
  493. HRESULT hr;
  494. ADOX::TablesPtr ptables;
  495. hr = pcatalog->get_Tables(&ptables);
  496. if (FAILED(hr))
  497. return hr;
  498. for (TableDesc *ptabledesc = g_rgtabledesc; ptabledesc->m_szName != NULL; ptabledesc++)
  499. {
  500. _bstr_t bstrTableName(ptabledesc->m_szName);
  501. ADOX::_TablePtr ptable;
  502. hr = ptable.CreateInstance(__uuidof(ADOX::Table));
  503. if (FAILED(hr))
  504. return hr;
  505. hr = ptable->put_Name(bstrTableName);
  506. if (FAILED(hr))
  507. return hr;
  508. hr = ptable->put_ParentCatalog(pcatalog);
  509. if (FAILED(hr))
  510. return hr;
  511. ADOX::ColumnsPtr pcols;
  512. hr = ptable->get_Columns(&pcols);
  513. if (FAILED(hr))
  514. return hr;
  515. ColumnDesc *pcolumndesc;
  516. for (pcolumndesc = ptabledesc->m_rgcolumndesc;
  517. pcolumndesc->m_szName != NULL; pcolumndesc++)
  518. {
  519. _bstr_t bstrColumnName(pcolumndesc->m_szName);
  520. _variant_t varColumnName(bstrColumnName);
  521. long type = pcolumndesc->m_type;
  522. long size = pcolumndesc->m_size;
  523. switch (type)
  524. {
  525. case ADOX::adVarWChar:
  526. //UNDONE: Must handle strings > 255 with Jet.
  527. if (!m_fSQLServer && (size > 255))
  528. size = 255;
  529. break;
  530. }
  531. hr = pcols->Append(varColumnName, pcolumndesc->m_type, size);
  532. ADOX::_Column *pcolumn;
  533. hr = pcols->get_Item(varColumnName, &pcolumn);
  534. if (pcolumndesc->m_fAutoIncrement || pcolumndesc->m_fAllowNulls
  535. || (pcolumndesc->m_type == ADOX::adVarWChar))
  536. {
  537. ADOX::PropertiesPtr pprops;
  538. hr = pcolumn->get_Properties(&pprops);
  539. #if 0
  540. long cProps;
  541. pprops->get_Count(&cProps);
  542. for (long i = 0; i < cProps; i++)
  543. {
  544. ADOX::PropertyPtr pprop;
  545. CComBSTR bstrName;
  546. pprops->get_Item(_variant_t(i), &pprop);
  547. pprop->get_Name(&bstrName);
  548. }
  549. #endif
  550. if (pcolumndesc->m_fAutoIncrement)
  551. {
  552. ADOX::PropertyPtr pprop;
  553. hr = pprops->get_Item(_variant_t(_T("AutoIncrement")), &pprop);
  554. pprop->put_Value(_variant_t((bool) TRUE));
  555. }
  556. if (pcolumndesc->m_fAllowNulls)
  557. {
  558. ADOX::PropertyPtr pprop;
  559. hr = pprops->get_Item(_variant_t(_T("Nullable")), &pprop);
  560. if (SUCCEEDED(hr))
  561. pprop->put_Value(_variant_t((bool) TRUE));
  562. }
  563. if (pcolumndesc->m_type == ADOX::adVarWChar)
  564. {
  565. ADOX::PropertyPtr pprop;
  566. hr = pprops->get_Item(_variant_t(_T("Jet OLEDB:Allow Zero Length")), &pprop);
  567. if (SUCCEEDED(hr))
  568. pprop->put_Value(_variant_t((bool) TRUE));
  569. }
  570. }
  571. }
  572. ADOX::IndexesPtr pindexes;
  573. hr = ptable->get_Indexes(&pindexes);
  574. if (ptabledesc->m_pindexdescPrimary != NULL)
  575. {
  576. hr = AddIndex(pindexes, ptabledesc->m_pindexdescPrimary, TRUE);
  577. _ASSERTE(SUCCEEDED(hr));
  578. }
  579. if (ptabledesc->m_rgindexdesc != NULL)
  580. {
  581. for (IndexDesc *pindexdesc = ptabledesc->m_rgindexdesc;
  582. pindexdesc->m_szName != NULL; pindexdesc++)
  583. {
  584. hr = AddIndex(pindexes, pindexdesc, FALSE);
  585. _ASSERTE(SUCCEEDED(hr));
  586. }
  587. }
  588. hr = ptables->Append(_variant_t((IDispatch *)ptable));
  589. }
  590. return hr;
  591. }
  592. HRESULT CGuideDB::OpenDB(IGuideStore *pgs, const TCHAR *szDBName)
  593. {
  594. HRESULT hr = E_FAIL;
  595. DeclarePerfTimer("CGuideDB::OpenDB");
  596. if (m_pdb == NULL)
  597. {
  598. ADODB::_ConnectionPtr pdb;
  599. TCHAR szConnection[4096];
  600. const TCHAR *szConnectionTemplate = g_szConnection;
  601. if (szDBName[0] == _T('*'))
  602. {
  603. m_fSQLServer = TRUE;
  604. szConnectionTemplate = g_szConnectionSQL;
  605. szDBName++;
  606. }
  607. wsprintf(szConnection, szConnectionTemplate, szDBName);
  608. hr = pdb.CreateInstance(__uuidof(ADODB::Connection));
  609. if (FAILED(hr))
  610. return hr;
  611. for (int cTries = 2; cTries > 0; cTries--)
  612. {
  613. PerfTimerReset();
  614. hr = pdb->Open(_bstr_t(szConnection), /*g_bstrDBUser*/ _T(""), /*g_bstrDBPassword*/ _T(""), 0);
  615. PerfTimerDump("Open");
  616. if (SUCCEEDED(hr))
  617. break;
  618. TCHAR szFilename[MAX_PATH];
  619. wsprintf(szFilename, _T("f:\\tmp\\%s.mdf"), szDBName);
  620. hr = CreateDB(szDBName, szFilename, szConnection);
  621. if (FAILED(hr))
  622. return hr;
  623. }
  624. m_pdb = pdb;
  625. }
  626. _variant_t varDB((IDispatch *)m_pdb);
  627. if (m_fSQLServer)
  628. {
  629. hr = m_pdb->put_CursorLocation(ADODB::adUseClient);
  630. }
  631. if (m_prsStrings == NULL)
  632. {
  633. ADODB::_RecordsetPtr prs;
  634. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  635. if (FAILED(hr))
  636. return hr;
  637. hr = prs->Open(g_varStrings, varDB, ADODB::adOpenUnspecified,
  638. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  639. if (FAILED(hr))
  640. return hr;
  641. m_prsStrings = prs;
  642. hr = m_prsStrings->MoveFirst();
  643. // First string is the version/uuid for the database
  644. _bstr_t bstrUUID;
  645. if (FAILED(hr))
  646. {
  647. UUID uuid;
  648. hr = UuidCreate(&uuid);
  649. if (hr != RPC_S_OK)
  650. return E_FAIL;
  651. OLECHAR sz[40];
  652. StringFromGUID2(uuid, sz, sizeof(sz)/sizeof(OLECHAR));
  653. bstrUUID = sz;
  654. m_prsStrings->AddNew();
  655. m_prsStrings->Fields->Item[g_bstrValue]->Value = bstrUUID;
  656. m_prsStrings->Update();
  657. }
  658. else
  659. {
  660. bstrUUID = m_prsStrings->Fields->Item[g_bstrValue]->Value;
  661. }
  662. }
  663. if (m_prsPropSets == NULL)
  664. {
  665. ADODB::_RecordsetPtr prs;
  666. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  667. if (FAILED(hr))
  668. return hr;
  669. hr = prs->Open(g_varPropertySets, varDB, ADODB::adOpenUnspecified,
  670. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  671. if (FAILED(hr))
  672. return hr;
  673. m_prsPropSets = prs;
  674. }
  675. if (m_prsPropTypes == NULL)
  676. {
  677. ADODB::_RecordsetPtr prs;
  678. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  679. if (FAILED(hr))
  680. return hr;
  681. hr = prs->Open(g_varPropertyTypes, varDB, ADODB::adOpenUnspecified,
  682. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  683. if (FAILED(hr))
  684. return hr;
  685. hr = prs->put_Index(_T("idPropSet"));
  686. m_prsPropTypes = prs;
  687. }
  688. if (m_prsProps == NULL)
  689. {
  690. ADODB::_RecordsetPtr prs;
  691. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  692. if (FAILED(hr))
  693. return hr;
  694. hr = prs->Open(g_varProperties, varDB, ADODB::adOpenUnspecified,
  695. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  696. if (FAILED(hr))
  697. return hr;
  698. m_prsProps = prs;
  699. }
  700. if (m_prsPropsIndexed == NULL)
  701. {
  702. if (m_fSQLServer)
  703. {
  704. hr = NewQuery("SELECT * FROM Properties"
  705. " ORDER BY Properties.idObj, Properties.idPropType, "
  706. "Properties.idProvider, Properties.idLanguage;",
  707. &m_prsPropsIndexed);
  708. }
  709. else
  710. {
  711. ADODB::_RecordsetPtr prs;
  712. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  713. if (FAILED(hr))
  714. return hr;
  715. hr = prs->Open(g_varProperties, varDB, ADODB::adOpenUnspecified,
  716. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  717. if (FAILED(hr))
  718. return hr;
  719. hr = prs->put_Index(_bstr_t("PK_Properties"));
  720. m_prsPropsIndexed = prs;
  721. }
  722. }
  723. if (m_prsObjTypes == NULL)
  724. {
  725. ADODB::_RecordsetPtr prs;
  726. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  727. if (FAILED(hr))
  728. return hr;
  729. hr = prs->Open(g_varObjectTypes, varDB, ADODB::adOpenUnspecified,
  730. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  731. if (FAILED(hr))
  732. return hr;
  733. m_prsObjTypes = prs;
  734. }
  735. hr = pgs->get_MetaPropertySets(&m_ppropsets);
  736. if (FAILED(hr))
  737. return hr;
  738. CategoriesPropSet::Init(m_ppropsets);
  739. ChannelPropSet::Init(m_ppropsets);
  740. ChannelsPropSet::Init(m_ppropsets);
  741. TimePropSet::Init(m_ppropsets);
  742. DescriptionPropSet::Init(m_ppropsets);
  743. CopyrightPropSet::Init(m_ppropsets);
  744. ProviderPropSet::Init(m_ppropsets);
  745. ScheduleEntryPropSet::Init(m_ppropsets);
  746. ServicePropSet::Init(m_ppropsets);
  747. RatingsPropSet::Init(m_ppropsets);
  748. MPAARatingsPropSet::Init(m_ppropsets);
  749. // Preload all the standard properties
  750. CComPtr<IMetaPropertyType> pproptype;
  751. pproptype = DescriptionPropSet::IDMetaPropertyType();
  752. pproptype = DescriptionPropSet::NameMetaPropertyType();
  753. pproptype = DescriptionPropSet::TitleMetaPropertyType();
  754. pproptype = DescriptionPropSet::SubtitleMetaPropertyType();
  755. pproptype = DescriptionPropSet::OneSentenceMetaPropertyType();
  756. pproptype = DescriptionPropSet::OneParagraphMetaPropertyType();
  757. pproptype = DescriptionPropSet::VersionMetaPropertyType();
  758. pproptype = TimePropSet::StartMetaPropertyType();
  759. pproptype = TimePropSet::EndMetaPropertyType();
  760. pproptype = CopyrightPropSet::TextMetaPropertyType();
  761. pproptype = CopyrightPropSet::DateMetaPropertyType();
  762. pproptype = ServicePropSet::TuneRequestMetaPropertyType();
  763. pproptype = ChannelPropSet::ServiceMetaPropertyType();
  764. pproptype = ChannelsPropSet::ChannelMetaPropertyType();
  765. pproptype = ScheduleEntryPropSet::ServiceMetaPropertyType();
  766. pproptype = ScheduleEntryPropSet::ProgramMetaPropertyType();
  767. pproptype = RatingsPropSet::MinimumAgeMetaPropertyType();
  768. pproptype = RatingsPropSet::SexMetaPropertyType();
  769. pproptype = RatingsPropSet::ViolenceMetaPropertyType();
  770. pproptype = RatingsPropSet::LanguageMetaPropertyType();
  771. pproptype = MPAARatingsPropSet::RatingMetaPropertyType();
  772. pproptype = CategoriesPropSet::Reserved_00MetaPropertyType();
  773. pproptype = CategoriesPropSet::MovieMetaPropertyType();
  774. pproptype = CategoriesPropSet::SportsMetaPropertyType();
  775. pproptype = CategoriesPropSet::SpecialMetaPropertyType();
  776. pproptype = CategoriesPropSet::SeriesMetaPropertyType();
  777. pproptype = CategoriesPropSet::NewsMetaPropertyType();
  778. pproptype = CategoriesPropSet::ShoppingMetaPropertyType();
  779. pproptype = CategoriesPropSet::Reserved_07MetaPropertyType();
  780. pproptype = CategoriesPropSet::Reserved_08MetaPropertyType();
  781. pproptype = CategoriesPropSet::Reserved_09MetaPropertyType();
  782. pproptype = CategoriesPropSet::Reserved_0AMetaPropertyType();
  783. pproptype = CategoriesPropSet::Reserved_0BMetaPropertyType();
  784. pproptype = CategoriesPropSet::Reserved_0CMetaPropertyType();
  785. pproptype = CategoriesPropSet::Reserved_0DMetaPropertyType();
  786. pproptype = CategoriesPropSet::Reserved_0EMetaPropertyType();
  787. pproptype = CategoriesPropSet::Reserved_0FMetaPropertyType();
  788. pproptype = CategoriesPropSet::ActionMetaPropertyType();
  789. pproptype = CategoriesPropSet::AdventureMetaPropertyType();
  790. pproptype = CategoriesPropSet::ChildrenMetaPropertyType();
  791. pproptype = CategoriesPropSet::ComedyMetaPropertyType();
  792. pproptype = CategoriesPropSet::DramaMetaPropertyType();
  793. pproptype = CategoriesPropSet::FantasyMetaPropertyType();
  794. pproptype = CategoriesPropSet::HorrorMetaPropertyType();
  795. pproptype = CategoriesPropSet::MusicalMetaPropertyType();
  796. pproptype = CategoriesPropSet::RomanceMetaPropertyType();
  797. pproptype = CategoriesPropSet::SciFiMetaPropertyType();
  798. pproptype = CategoriesPropSet::WesternMetaPropertyType();
  799. pproptype = CategoriesPropSet::BaseballMetaPropertyType();
  800. pproptype = CategoriesPropSet::BasketballMetaPropertyType();
  801. pproptype = CategoriesPropSet::BoxingMetaPropertyType();
  802. pproptype = CategoriesPropSet::FootballMetaPropertyType();
  803. pproptype = CategoriesPropSet::GolfMetaPropertyType();
  804. pproptype = CategoriesPropSet::HockeyMetaPropertyType();
  805. pproptype = CategoriesPropSet::RacingMetaPropertyType();
  806. pproptype = CategoriesPropSet::SkiingMetaPropertyType();
  807. pproptype = CategoriesPropSet::SoccerMetaPropertyType();
  808. pproptype = CategoriesPropSet::TennisMetaPropertyType();
  809. pproptype = CategoriesPropSet::WrestlingMetaPropertyType();
  810. pproptype = CategoriesPropSet::CulturalArtsMetaPropertyType();
  811. pproptype = CategoriesPropSet::EducationalMetaPropertyType();
  812. pproptype = CategoriesPropSet::GeneralInterestMetaPropertyType();
  813. pproptype = CategoriesPropSet::HowToMetaPropertyType();
  814. pproptype = CategoriesPropSet::MatureMetaPropertyType();
  815. pproptype = CategoriesPropSet::MusicMetaPropertyType();
  816. pproptype = CategoriesPropSet::ReligiousMetaPropertyType();
  817. pproptype = CategoriesPropSet::SoapOperaMetaPropertyType();
  818. pproptype = CategoriesPropSet::TalkMetaPropertyType();
  819. pproptype = CategoriesPropSet::BusinessMetaPropertyType();
  820. pproptype = CategoriesPropSet::CurrentMetaPropertyType();
  821. pproptype = CategoriesPropSet::WeatherMetaPropertyType();
  822. pproptype = CategoriesPropSet::HomeShoppingMetaPropertyType();
  823. pproptype = CategoriesPropSet::ProductInfoMetaPropertyType();
  824. pproptype = ProviderPropSet::NameMetaPropertyType();
  825. pproptype = ProviderPropSet::NetworkNameMetaPropertyType();
  826. pproptype = ProviderPropSet::DescriptionMetaPropertyType();
  827. hr = CreateEventSinkWindow();
  828. if (FAILED(hr))
  829. return hr;
  830. return hr;
  831. }
  832. HRESULT CGuideDB::get_RelsByID1Rel(ADODB::_Recordset **pprs)
  833. {
  834. HRESULT hr;
  835. if (m_prsRelsByID1Rel == NULL)
  836. {
  837. if (m_fSQLServer)
  838. {
  839. hr = NewQuery("SELECT * FROM ObjectRelationships"
  840. " ORDER BY ObjectRelationships.idObj1,"
  841. " ObjectRelationships.idRel, ObjectRelationships.[order];",
  842. &m_prsRelsByID1Rel);
  843. }
  844. else
  845. {
  846. _variant_t varDB((IDispatch *)m_pdb);
  847. ADODB::_RecordsetPtr prs;
  848. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  849. if (FAILED(hr))
  850. return hr;
  851. hr = prs->Open(g_varObjectRelationships, varDB, ADODB::adOpenUnspecified,
  852. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  853. if (FAILED(hr))
  854. return hr;
  855. hr = prs->put_Index(g_bstrIDObj1Rel);
  856. m_prsRelsByID1Rel = prs;
  857. }
  858. }
  859. *pprs = m_prsRelsByID1Rel;
  860. if (*pprs != NULL)
  861. (*pprs)->AddRef();
  862. return S_OK;
  863. }
  864. HRESULT CGuideDB::get_RelsByID2Rel(ADODB::_Recordset **pprs)
  865. {
  866. HRESULT hr;
  867. if (m_prsRelsByID2Rel == NULL)
  868. {
  869. if (m_fSQLServer)
  870. {
  871. hr = NewQuery("SELECT * FROM ObjectRelationships"
  872. " ORDER BY ObjectRelationships.idObj2,"
  873. " ObjectRelationships.idRel, ObjectRelationships.[order];",
  874. &m_prsRelsByID2Rel);
  875. }
  876. else
  877. {
  878. _variant_t varDB((IDispatch *)m_pdb);
  879. ADODB::_RecordsetPtr prs;
  880. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  881. if (FAILED(hr))
  882. return hr;
  883. hr = prs->Open(g_varObjectRelationships, varDB, ADODB::adOpenUnspecified,
  884. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  885. if (FAILED(hr))
  886. return hr;
  887. hr = prs->put_Index(g_bstrIDObj2Rel);
  888. m_prsRelsByID2Rel = prs;
  889. }
  890. }
  891. *pprs = m_prsRelsByID2Rel;
  892. if (*pprs != NULL)
  893. (*pprs)->AddRef();
  894. return S_OK;
  895. }
  896. HRESULT CGuideDB::get_ObjsRS(ADODB::_Recordset **pprs)
  897. {
  898. HRESULT hr;
  899. if (m_prsObjs == NULL)
  900. {
  901. _variant_t varDB((IDispatch *)m_pdb);
  902. ADODB::_RecordsetPtr prs;
  903. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  904. if (FAILED(hr))
  905. return hr;
  906. hr = prs->Open(g_varObjects, varDB, ADODB::adOpenUnspecified,
  907. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  908. if (FAILED(hr))
  909. return hr;
  910. m_prsObjs = prs;
  911. }
  912. *pprs = m_prsObjs;
  913. if (*pprs != NULL)
  914. (*pprs)->AddRef();
  915. return S_OK;
  916. }
  917. HRESULT CGuideDB::get_ObjsByType(ADODB::_Recordset **pprs)
  918. {
  919. HRESULT hr;
  920. if (m_prsObjsByType == NULL)
  921. {
  922. if (m_fSQLServer)
  923. {
  924. hr = NewQuery("SELECT * FROM Objects ORDER BY Objects.idType;", &m_prsObjsByType);
  925. }
  926. else
  927. {
  928. _variant_t varDB((IDispatch *)m_pdb);
  929. ADODB::_RecordsetPtr prs;
  930. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  931. if (FAILED(hr))
  932. return hr;
  933. hr = prs->Open(g_varObjects, varDB, ADODB::adOpenUnspecified,
  934. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  935. if (FAILED(hr))
  936. return hr;
  937. hr = prs->put_Index(g_bstrIDType);
  938. m_prsObjsByType = prs;
  939. }
  940. }
  941. *pprs = m_prsObjsByType;
  942. if (*pprs != NULL)
  943. (*pprs)->AddRef();
  944. return S_OK;
  945. }
  946. HRESULT CGuideDB::get_ObjsByID(ADODB::_Recordset **pprs)
  947. {
  948. HRESULT hr;
  949. if (m_prsObjsByID == NULL)
  950. {
  951. _variant_t varDB((IDispatch *)m_pdb);
  952. ADODB::_RecordsetPtr prs;
  953. hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
  954. if (FAILED(hr))
  955. return hr;
  956. hr = prs->Open(g_varObjects, varDB, ADODB::adOpenUnspecified,
  957. ADODB::adLockPessimistic, ADODB::adCmdTableDirect);
  958. if (FAILED(hr))
  959. return hr;
  960. hr = prs->put_Index(_T("PK_Objects"));
  961. m_prsObjsByID = prs;
  962. }
  963. *pprs = m_prsObjsByID;
  964. if (*pprs != NULL)
  965. (*pprs)->AddRef();
  966. return S_OK;
  967. }
  968. HRESULT CGuideDB::get_MetaPropertyType(long idPropType, IMetaPropertyType **ppproptype)
  969. {
  970. *ppproptype = NULL;
  971. t_mapPropTypes::iterator it = m_mapPropTypes.find(idPropType);
  972. if (it == m_mapPropTypes.end())
  973. return E_INVALIDARG;
  974. *ppproptype = (*it).second;
  975. (*ppproptype)->AddRef();
  976. return S_OK;
  977. }
  978. HRESULT CGuideDB::put_MetaPropertyType(long idPropType, IMetaPropertyType *pproptype)
  979. {
  980. m_mapPropTypes[idPropType] = pproptype;
  981. pproptype->AddRef();
  982. return S_OK;
  983. }
  984. HRESULT CGuideDB::CacheObject(long idObj, long idType, IUnknown **ppobj)
  985. {
  986. HRESULT hr;
  987. CObjectType *pobjtype;
  988. if (idType == 0)
  989. {
  990. // Look it up
  991. ADODB::_RecordsetPtr prs;
  992. hr = get_ObjsByID(&prs);
  993. if (FAILED(hr))
  994. return hr;
  995. if (m_fSQLServer)
  996. {
  997. TCHAR szFind[32];
  998. prs->MoveFirst();
  999. wsprintf(szFind, _T("id = %d"), idObj);
  1000. hr = prs->Find(_bstr_t(szFind), 0, ADODB::adSearchForward);
  1001. }
  1002. else
  1003. {
  1004. _variant_t var(idObj);
  1005. hr = prs->Seek(var, ADODB::adSeekFirstEQ);
  1006. }
  1007. if (FAILED(hr))
  1008. return hr;
  1009. if (prs->EndOfFile)
  1010. return E_INVALIDARG;
  1011. idType = prs->Fields->Item[g_bstrIDType]->Value;
  1012. }
  1013. get_ObjectType(idType, &pobjtype);
  1014. return CacheObject(idObj, pobjtype, ppobj);
  1015. }
  1016. HRESULT CGuideDB::CacheObject(long idObj, CObjectType *pobjtype, IUnknown **ppobj)
  1017. {
  1018. HRESULT hr;
  1019. *ppobj = NULL;
  1020. *ppobj = m_cacheObj.get_Unknown(idObj);
  1021. if (*ppobj != NULL)
  1022. return S_OK;
  1023. hr = pobjtype->CreateInstance(idObj, ppobj);
  1024. if (FAILED(hr))
  1025. return hr;
  1026. hr = m_cacheObj.Cache(idObj, *ppobj);
  1027. if (FAILED(hr))
  1028. return hr;
  1029. CComQIPtr<CObject> pobj(*ppobj);
  1030. return pobj->Load();
  1031. }
  1032. HRESULT CGuideDB::UncacheObject(long idObj)
  1033. {
  1034. m_cacheObj.Uncache(idObj);
  1035. return S_OK;
  1036. }
  1037. HRESULT CGuideDB::get_MetaPropertiesOf(long id, IMetaProperties **ppprops)
  1038. {
  1039. *ppprops = NULL;
  1040. t_mapIdProps::iterator it = m_mapIdProps.find(id);
  1041. if (it != m_mapIdProps.end())
  1042. {
  1043. *ppprops = (*it).second;
  1044. (*ppprops)->AddRef();
  1045. return S_OK;
  1046. }
  1047. CComPtr<CMetaProperties> pprops = NewComObject(CMetaProperties);
  1048. if (pprops != NULL)
  1049. pprops->Init(id, 0, this);
  1050. *ppprops = pprops;
  1051. (*ppprops)->AddRef();
  1052. m_mapIdProps[id] = pprops.Detach();
  1053. return S_OK;
  1054. }
  1055. HRESULT CGuideDB::get_IdOf(IUnknown *pobj, long *pid)
  1056. {
  1057. *pid = m_cacheObj.get_ID(pobj);
  1058. return (*pid == 0) ? E_INVALIDARG : S_OK;
  1059. }
  1060. HRESULT CGuideDB::get_Object(long idObj, IUnknown **ppobj)
  1061. {
  1062. *ppobj = m_cacheObj.get_Unknown(idObj);
  1063. if (*ppobj == NULL)
  1064. return E_INVALIDARG;
  1065. return S_OK;
  1066. }
  1067. HRESULT CGuideDB::get_ObjectsWithType(long idType, IObjects **ppobjs)
  1068. {
  1069. *ppobjs = NULL;
  1070. t_mapObjsWithType::iterator it = m_mapObjsWithType.find(idType);
  1071. if (it == m_mapObjsWithType.end())
  1072. return S_FALSE;
  1073. *ppobjs = (*it).second;
  1074. (*ppobjs)->AddRef();
  1075. return S_OK;
  1076. }
  1077. HRESULT CGuideDB::get_ObjectsWithType(CObjectType *pobjtype, IObjects **ppobjs)
  1078. {
  1079. HRESULT hr;
  1080. long idType;
  1081. *ppobjs = NULL;
  1082. hr = pobjtype->get_ID(&idType);
  1083. if (FAILED(hr))
  1084. return hr;
  1085. hr = get_ObjectsWithType(idType, ppobjs);
  1086. if (hr == S_OK)
  1087. return S_OK;
  1088. hr = pobjtype->get_NewCollection(ppobjs);
  1089. if (FAILED(hr))
  1090. return hr;
  1091. m_mapObjsWithType[idType] = *ppobjs;
  1092. (*ppobjs)->AddRef();
  1093. return S_OK;
  1094. }
  1095. void CGuideDB::Broadcast_ItemEvent(enum ItemEvent ev, long idObj, long idType)
  1096. {
  1097. HRESULT hr;
  1098. if (m_iTransLevel == 0)
  1099. {
  1100. if (m_rgmsgItemEvent[ev] != NULL)
  1101. PostMessage(HWND_BROADCAST, m_rgmsgItemEvent[ev], idObj, idType);
  1102. }
  1103. else
  1104. {
  1105. CComPtr<IObjects> pobjs;
  1106. hr = get_ObjectsWithType(idType, &pobjs);
  1107. if (hr != S_OK)
  1108. return;
  1109. CComQIPtr<CObjects> pobjsT(pobjs);
  1110. pobjsT->NoteChanged(idObj);
  1111. }
  1112. }
  1113. void CGuideDB::Broadcast_ItemChanged(long idObj)
  1114. {
  1115. HRESULT hr;
  1116. CComPtr<IUnknown> punk = m_cacheObj.get_Unknown(idObj);
  1117. if (punk == NULL)
  1118. return;
  1119. CComQIPtr<CObject> pobj(punk);
  1120. if (pobj == NULL)
  1121. return;
  1122. CObjectType *ptype;
  1123. hr = pobj->get_Type(&ptype);
  1124. if (FAILED(hr))
  1125. return;
  1126. long idType;
  1127. hr = ptype->get_ID(&idType);
  1128. if (FAILED(hr))
  1129. return;
  1130. Broadcast_ItemEvent(Changed, idObj, idType);
  1131. }
  1132. void CGuideDB::TransactionDone(boolean fCommit)
  1133. {
  1134. t_mapObjsWithType::iterator it;
  1135. for (it = m_mapObjsWithType.begin(); it != m_mapObjsWithType.end(); it++)
  1136. {
  1137. CComPtr<IObjects> pobjs = (*it).second;
  1138. CComQIPtr<CObjects> pobjsT(pobjs);
  1139. pobjsT->TransactionDone(fCommit);
  1140. }
  1141. }
  1142. void CGuideDB::Fire_ItemEvent(enum ItemEvent ev, long idObj, long idType)
  1143. {
  1144. HRESULT hr;
  1145. CComPtr<IUnknown> pobj;
  1146. CComPtr<IObjects> pobjs;
  1147. if (idType == NULL)
  1148. return;
  1149. RequeryObjectsTables();
  1150. hr = get_ObjectsWithType(idType, &pobjs);
  1151. if (hr != S_OK)
  1152. return;
  1153. if ((idObj != NULL) && (ev != Removed))
  1154. {
  1155. hr = CacheObject(idObj, (long) 0, &pobj);
  1156. if (FAILED(hr))
  1157. return;
  1158. }
  1159. CComQIPtr<CObjects> pobjsT(pobjs);
  1160. switch (ev)
  1161. {
  1162. case Added:
  1163. hr = pobjsT->Notify_ItemAdded(pobj);
  1164. break;
  1165. case Removed:
  1166. hr = pobjsT->Notify_ItemRemoved(idObj);
  1167. break;
  1168. case Changed:
  1169. hr = pobjsT->Notify_ItemChanged(pobj);
  1170. break;
  1171. }
  1172. }
  1173. HRESULT CGuideDB::get_ObjectType(long idObjType, CObjectType **ppobjtype)
  1174. {
  1175. *ppobjtype = NULL;
  1176. t_mapObjTypes::iterator it = m_mapObjTypes.find(idObjType);
  1177. if (it == m_mapObjTypes.end())
  1178. return E_INVALIDARG;
  1179. *ppobjtype = (*it).second;
  1180. return S_OK;
  1181. }
  1182. HRESULT CGuideDB::put_ObjectType(long idObjType, CObjectType *pobjtype)
  1183. {
  1184. m_mapObjTypes[idObjType] = pobjtype;
  1185. return S_OK;
  1186. }
  1187. HRESULT CGuideDB::get_ObjectTypes(CObjectTypes **ppobjtypes)
  1188. {
  1189. if (m_pobjtypes == NULL)
  1190. {
  1191. m_pobjtypes = new CObjectTypes;
  1192. if (m_pobjtypes == NULL)
  1193. return E_OUTOFMEMORY;
  1194. m_pobjtypes->Init(this);
  1195. }
  1196. *ppobjtypes = m_pobjtypes;
  1197. return S_OK;
  1198. }
  1199. HRESULT CGuideDB::get_ObjectType(CLSID clsid, CObjectType **ppobjtype)
  1200. {
  1201. OLECHAR sz[40];
  1202. StringFromGUID2(clsid, sz, sizeof(sz)/sizeof(OLECHAR));
  1203. _bstr_t bstrCLSID(sz);
  1204. return get_ObjectType(bstrCLSID, ppobjtype);
  1205. }
  1206. HRESULT CGuideDB::get_ObjectType(BSTR bstrCLSID, CObjectType **ppobjtype)
  1207. {
  1208. CObjectTypes *pobjtypes;
  1209. HRESULT hr = get_ObjectTypes(&pobjtypes);
  1210. if (FAILED(hr))
  1211. return hr;
  1212. hr = pobjtypes->get_AddNew(bstrCLSID, ppobjtype);
  1213. if (FAILED(hr))
  1214. return hr;
  1215. return S_OK;
  1216. }
  1217. long CGuideDB::GetIDGuideDataProvider()
  1218. {
  1219. if (m_pdataprovider == NULL)
  1220. return 0;
  1221. long id;
  1222. get_IdOf(m_pdataprovider, &id);
  1223. return id;
  1224. }
  1225. HRESULT CGuideDB::get_GuideDataProvider(IGuideDataProvider **ppdataprovider)
  1226. {
  1227. *ppdataprovider = m_pdataprovider;
  1228. if (*ppdataprovider != NULL)
  1229. (*ppdataprovider)->AddRef();
  1230. return S_OK;
  1231. }
  1232. HRESULT CGuideDB::putref_GuideDataProvider(IGuideDataProvider *pdataprovider)
  1233. {
  1234. if (pdataprovider == NULL)
  1235. {
  1236. m_pdataprovider = NULL;
  1237. return S_OK;
  1238. }
  1239. return pdataprovider->QueryInterface(__uuidof(IGuideDataProvider), (void **)&m_pdataprovider);
  1240. }
  1241. HRESULT CGuideDB::SaveObject(IUnknown *punk, long *pid)
  1242. {
  1243. HRESULT hr;
  1244. boolean fNew = FALSE;
  1245. CComQIPtr<CObject> pobj(punk);
  1246. if (pobj == NULL)
  1247. {
  1248. fNew = TRUE;
  1249. CComQIPtr<IPersist> ppersist(punk);
  1250. if (ppersist == NULL)
  1251. return E_INVALIDARG;
  1252. CLSID clsid;
  1253. hr = ppersist->GetClassID(&clsid);
  1254. if (FAILED(hr))
  1255. return hr;
  1256. CObjectType *pobjtype;
  1257. hr = get_ObjectType(clsid, &pobjtype);
  1258. CComPtr<IUnknown> punkObj;
  1259. hr = pobjtype->get_New(&punkObj);
  1260. if (FAILED(hr))
  1261. return hr;
  1262. pobj = punkObj;
  1263. if (pobj == NULL)
  1264. return E_FAIL;
  1265. }
  1266. pobj->get_ID(pid);
  1267. pobj->Save(punk);
  1268. if (fNew)
  1269. pobj->Load();
  1270. return S_OK;
  1271. }
  1272. void CGuideDB::DumpObjsCache(const TCHAR *psz, boolean fPurge)
  1273. {
  1274. #ifdef _DEBUG
  1275. OutputDebugString(psz);
  1276. #endif
  1277. long cItems = m_cacheObjs.Count();
  1278. for (int i = 0; i < cItems; i++)
  1279. {
  1280. CComQIPtr<CObjects> pobjs(m_cacheObjs.Item(i));
  1281. pobjs->Dump();
  1282. if (fPurge)
  1283. pobjs->Resync();
  1284. }
  1285. }