DatabaseUtilities.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. // DatabaseUtilites.cpp: implementation of the CDatabaseUtilites class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CP_Main.h"
  6. #include "DatabaseUtilities.h"
  7. #include <io.h>
  8. //////////////////////////////////////////////////////////////////////
  9. // Construction/Destruction
  10. //////////////////////////////////////////////////////////////////////
  11. BOOL DoCleanups()
  12. {
  13. try
  14. {
  15. //Try and open mText if it's not there then create it
  16. CDaoRecordset recset(theApp.EnsureOpenDB());
  17. recset.Open(AFX_DAO_USE_DEFAULT_TYPE, "SELECT mText FROM Main", 0);
  18. recset.Close();
  19. }
  20. catch(CDaoException* e)
  21. {
  22. e->Delete();
  23. try
  24. {
  25. theApp.EnsureOpenDB();
  26. theApp.m_pDatabase->Execute("ALTER TABLE Main ADD COLUMN mText MEMO", dbFailOnError);
  27. theApp.m_pDatabase->Execute("UPDATE Main SET mText=strText", dbFailOnError);
  28. theApp.m_pDatabase->Execute("ALTER TABLE Main DROP COLUMN strText", dbFailOnError);
  29. theApp.m_pDatabase->Execute("ALTER TABLE Main DROP COLUMN strType", dbFailOnError);
  30. }
  31. catch(CDaoException *e)
  32. {
  33. CString cs;
  34. cs = e->m_pErrorInfo->m_strDescription;
  35. cs += "\n\nError updating Database!";
  36. MessageBox(NULL, cs, "Ditto", MB_OK);
  37. e->Delete();
  38. return FALSE;
  39. }
  40. }
  41. return TRUE;
  42. }
  43. CString GetDBName()
  44. {
  45. return CGetSetOptions::GetDBPath();
  46. }
  47. CString GetDefaultDBName()
  48. {
  49. CString csDefaultPath;
  50. LPMALLOC pMalloc;
  51. if(SUCCEEDED(::SHGetMalloc(&pMalloc)))
  52. {
  53. LPITEMIDLIST pidlPrograms;
  54. SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidlPrograms);
  55. char string[MAX_PATH];
  56. SHGetPathFromIDList(pidlPrograms, string);
  57. pMalloc->Free(pidlPrograms);
  58. pMalloc->Release();
  59. csDefaultPath = string;
  60. csDefaultPath += "\\Ditto\\";
  61. if(_access(csDefaultPath, 0) == -1)
  62. CreateDirectory(csDefaultPath, NULL);
  63. csDefaultPath += DEFAULT_DB_NAME;
  64. }
  65. return csDefaultPath;
  66. }
  67. BOOL CheckDBExists(CString csDBPath)
  68. {
  69. if(_access(csDBPath, 0) == -1)
  70. {
  71. //Database didn't exist
  72. CGetSetOptions::SetDBPath("");
  73. // -- create a new one
  74. CreateDB(GetDefaultDBName());
  75. return TRUE;
  76. }
  77. BOOL bRet = FALSE;
  78. if(ValidDB(csDBPath) == FALSE)
  79. {
  80. theApp.CloseDB();
  81. CGetSetOptions::SetDBPath("");
  82. //Db existed but was bad
  83. CString csMarkAsBad;
  84. csMarkAsBad = csDBPath;
  85. csMarkAsBad.Replace(".", "_BAD.");
  86. CString csPath = GetDefaultDBName();
  87. CString cs;
  88. cs.Format("Unrecognized Database Format \"%s\",\n"
  89. "the file will be renamed \"%s\",\n"
  90. "and a new database will be created,\n"
  91. "\"%s\"", csDBPath, csMarkAsBad, csPath);
  92. AfxMessageBox(cs);
  93. CFile::Rename(csDBPath, csMarkAsBad);
  94. bRet = CreateDB(csPath);
  95. }
  96. else
  97. bRet = TRUE;
  98. return bRet;
  99. }
  100. BOOL ValidDB(CString csPath)
  101. {
  102. try
  103. {
  104. CDaoDatabase db;
  105. db.Open(csPath);
  106. CDaoTableDef table(&db);
  107. CDaoFieldInfo info;
  108. table.Open("Main");
  109. table.Close();
  110. table.Open("Data");
  111. table.Close();
  112. table.Open("Types");
  113. table.Close();
  114. }
  115. catch(CDaoException* e)
  116. {
  117. e->Delete();
  118. ASSERT(FALSE);
  119. return FALSE;
  120. }
  121. return TRUE;
  122. }
  123. BOOL CreateDB(CString csPath)
  124. {
  125. CDaoDatabase db;
  126. try
  127. {
  128. EnsureDirectory(csPath);
  129. db.Create(csPath);
  130. CDaoTableDefEx table(&db);
  131. //Creat the Main table
  132. table.Create("Main");
  133. table.CreateField("lID", dbLong, 4, dbAutoIncrField);
  134. table.CreateIndex(TRUE, "lID");
  135. table.CreateField("lDate", dbLong, 4, 0, "0");
  136. table.CreateIndex(FALSE, "lDate");
  137. table.CreateField("mText", dbMemo, 0, dbVariableField);
  138. // table.CreateField("strText", dbText, 250, dbVariableField);
  139. table.CreateField("lShortCut", dbLong, 4, 0, "0");
  140. table.CreateIndex(FALSE, "lShortCut");
  141. table.CreateField("lDontAutoDelete", dbLong, 4, 0, "0");
  142. table.CreateField("lTotalCopySize", dbLong, 4, 0, "0");
  143. table.Append();
  144. table.Close();
  145. //Create the Data Table
  146. table.Create("Data");
  147. table.CreateField("lID", dbLong, 4, dbAutoIncrField);
  148. table.CreateIndex(TRUE, "lID");
  149. table.CreateField("lParentID", dbLong, 4, 0, "0");
  150. table.CreateIndex(FALSE, "lParentID");
  151. table.CreateField("strClipBoardFormat", dbText, 50, dbVariableField);
  152. table.CreateField("ooData", dbLongBinary, 0);
  153. table.Append();
  154. table.Close();
  155. //Create the Types table
  156. table.Create("Types");
  157. table.CreateField("ID", dbLong, 4, dbAutoIncrField);
  158. table.CreateField("TypeText", dbText, 50, dbVariableField);
  159. table.Append();
  160. table.Close();
  161. db.Close();
  162. return TRUE;
  163. }
  164. catch(CDaoException *e)
  165. {
  166. ASSERT(FALSE);
  167. e->Delete();
  168. }
  169. return FALSE;
  170. }
  171. BOOL CompactDatabase()
  172. {
  173. if(!theApp.CloseDB())
  174. return FALSE;
  175. CString csDBName = GetDBName();
  176. CString csTempDBName = csDBName;
  177. csTempDBName.Replace(".mdb", "TempDBName.mdb");
  178. //Compact the database
  179. try
  180. {
  181. CDaoWorkspace::CompactDatabase(csDBName, csTempDBName);//, dbLangGeneral, 0, "andrew");//DATABASE_PASSWORD);
  182. }
  183. catch(CDaoException* e)
  184. {
  185. AfxMessageBox(e->m_pErrorInfo->m_strDescription);
  186. DeleteFile(csTempDBName);
  187. e->Delete();
  188. return FALSE;
  189. }
  190. catch(CMemoryException* e)
  191. {
  192. AfxMessageBox("Memory Exception");
  193. DeleteFile(csTempDBName);
  194. e->Delete();
  195. return FALSE;
  196. }
  197. //Since compacting the database creates a new db delete the old one and replace it
  198. //with the compacted db
  199. if(DeleteFile(csDBName))
  200. {
  201. try
  202. {
  203. CFile::Rename(csTempDBName, csDBName);
  204. }
  205. catch(CFileException *e)
  206. {
  207. e->ReportError();
  208. e->Delete();
  209. return FALSE;
  210. }
  211. }
  212. else
  213. AfxMessageBox("Error Compacting Database");
  214. return TRUE;
  215. }
  216. BOOL RepairDatabase()
  217. {
  218. if(!theApp.CloseDB())
  219. return FALSE;
  220. try
  221. {
  222. CDaoWorkspace::RepairDatabase(GetDBName());
  223. }
  224. catch(CDaoException *e)
  225. {
  226. AfxMessageBox(e->m_pErrorInfo->m_strDescription);
  227. e->Delete();
  228. return FALSE;
  229. }
  230. return TRUE;
  231. }
  232. BOOL RemoveOldEntries()
  233. {
  234. if(CGetSetOptions::GetCheckForMaxEntries())
  235. {
  236. long lMax = CGetSetOptions::GetMaxEntries();
  237. CMainTable recset;
  238. recset.Open("SELECT * FROM Main ORDER BY lDate DESC");
  239. if(!recset.IsEOF())
  240. {
  241. recset.MoveLast();
  242. long lCount = recset.GetRecordCount();
  243. ARRAY IDs;
  244. while((lCount > lMax) && (!recset.IsBOF()))
  245. {
  246. //Don't delete entries that have shorcuts or the flag set
  247. if(recset.m_lDontAutoDelete <= 0)
  248. IDs.Add(recset.m_lID);
  249. lCount--;
  250. recset.MovePrev();
  251. }
  252. CClip::Delete(IDs);
  253. }
  254. }
  255. if(CGetSetOptions::GetCheckForExpiredEntries())
  256. {
  257. long lExpire = CGetSetOptions::GetExpiredEntries();
  258. if(lExpire)
  259. {
  260. CTime now = CTime::GetCurrentTime();
  261. now -= CTimeSpan(lExpire, 0, 0, 0);
  262. CMainTable recset;
  263. recset.Open("SELECT * FROM Main "
  264. "WHERE lDate < %d AND "
  265. "lShortCut <= 0 AND lDontAutoDelete <= 0", now.GetTime());
  266. ARRAY IDs;
  267. while(!recset.IsEOF())
  268. {
  269. IDs.Add(recset.m_lID);
  270. recset.MoveNext();
  271. }
  272. CClip::Delete(IDs);
  273. }
  274. }
  275. return TRUE;
  276. }
  277. BOOL EnsureDirectory(CString csPath)
  278. {
  279. char drive[_MAX_DRIVE];
  280. char dir[_MAX_DIR];
  281. char fname[_MAX_FNAME];
  282. char ext[_MAX_EXT];
  283. _splitpath(csPath, drive, dir, fname, ext);
  284. CString csDir(drive);
  285. csDir += dir;
  286. if(_access(csDir, 0) == -1)
  287. {
  288. if(CreateDirectory(csDir, NULL))
  289. return TRUE;
  290. }
  291. else
  292. return TRUE;
  293. return FALSE;
  294. }