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.

478 lines
16KB

  1. #include "bdd.h"
  2. class_bdd::class_bdd(const wxString& path_in, wxGrid* grid_consults)
  3. {
  4. this->path_in = path_in;
  5. if (wxFileExists(path_in + slash + "db.lck"))
  6. {
  7. wxMessageBox(_T("La base est actuellement en cours d'utilisation.\nSi vous êtes certains que ce n'est pas le cas,\n(comme par exemple après un crash)\nsupprimez le fichier db.lck situé dans le même répertoire"));
  8. exit(0);
  9. }
  10. this->grid_consults = grid_consults;
  11. wxString path = path_in + slash + "cosmos.db";
  12. if (!wxFileExists(path))
  13. CreateEmpty(path);
  14. else if ((rc=sqlite3_open_v2(_C(path), &db, SQLITE_OPEN_READWRITE, NULL)) != SQLITE_OK)
  15. {
  16. wxMessageBox(_T("Erreur lors de l'ouverture de la base de données"), "Erreur", wxICON_ERROR | wxOK);
  17. exit(0);
  18. }
  19. wxFile* file_lock = new wxFile(path_in + slash + "db.lck", wxFile::write);
  20. file_lock->Close();
  21. }
  22. class_bdd::~class_bdd()
  23. {
  24. sqlite3_close(db);
  25. wxRemoveFile(path_in + slash + "db.lck");
  26. }
  27. void class_bdd::CreateEmpty(const wxString& path)
  28. {
  29. rc = 0;
  30. rc += sqlite3_open_v2(_C(path), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
  31. rc += sqlite3_exec(db, "CREATE TABLE Consult(id INTEGER PRIMARY KEY ASC, n_dossier INTEGER, nom VARCHAR(50), prenom VARCHAR(50), responsable VARCHAR(100), consultant VARCHAR(50), theme TEXT, etablissement VARCHAR(100), travail VARCHAR(50), date_cs DATE, service VARCHAR(100));", NULL, NULL, NULL);
  32. rc += sqlite3_exec(db, "CREATE TABLE Result(id INTEGER PRIMARY KEY ASC, publi BOOLEAN DEFAULT 0, publi_CHU BOOLEAN DEFAULT 0, cs_associe BOOLEAN DEFAULT 0, nb_result INTEGER DEFAULT 0, id_result TEXT DEFAULT \"\");", NULL, NULL, NULL);
  33. rc += sqlite3_exec(db, "CREATE TABLE Publi(id INTEGER PRIMARY KEY, titre TEXT, auteurs TEXT, abstract TEXT, revue TEXT, lien VARCHAR(50), date_publi TEXT, affiliation TEXT);", NULL, NULL, NULL);
  34. rc += sqlite3_exec(db, "CREATE TABLE Correc(orig TEXT PRIMARY KEY, dest TEXT);", NULL, NULL, NULL);
  35. if (rc)
  36. {
  37. wxMessageBox(_T("Erreur lors de la création de la base de données"), "Erreur", wxICON_ERROR | wxOK);
  38. exit(0);
  39. }
  40. }
  41. void class_bdd::Importer(const wxString& filename)
  42. {
  43. rc = 0;
  44. int size = 0;
  45. int progress = 0; //indicateurs de progression
  46. wxUniChar c;
  47. wxString content;
  48. bool inquote = false; //guillemets
  49. bool is_first_line = true;
  50. wxString item[23];
  51. wxFFile* file_import = new wxFFile();
  52. file_import->Open(filename);
  53. #ifdef __WXMSW__
  54. file_import->ReadAll(&content, wxConvAuto(wxFONTENCODING_SYSTEM));
  55. #elif defined(__WXGTK__)
  56. file_import->ReadAll(&content);
  57. #endif
  58. size = content.length() + 1;
  59. sqlite3_exec(db, "SAVEPOINT before_import;", NULL, NULL, NULL);
  60. wxProgressDialog dialog_progress("Import", "Import de la base...", size, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME | wxPD_CAN_ABORT);
  61. do
  62. {
  63. for (int i=0; i<22; i++) //boucle pour les 21 premiers items
  64. {
  65. item[i]="";
  66. do
  67. {
  68. c = content[progress];
  69. progress++;
  70. if (c == '"')
  71. {
  72. inquote = (!inquote) ? true : false;
  73. }
  74. if (c != '"')
  75. item[i] << c;
  76. }while (((c != ';') && (!inquote)) || inquote); //boucle pour un item, se finit par un ';' sauf entre guillemets
  77. item[i] = item[i].BeforeLast(';');
  78. }
  79. item[22]="";
  80. do
  81. {
  82. c = content[progress];
  83. progress++;
  84. if ((c != '\n') && (c != '\0'))
  85. item[22] << c;
  86. }while ((c != '\n') && (c != '\0')); //dernier item de la ligne, se finit si retour ou EOF
  87. if (!is_first_line)
  88. {
  89. //Insertion dans la table de consults
  90. wxString requete = "INSERT OR REPLACE INTO Consult (id, n_dossier, nom, prenom, responsable, consultant, theme, etablissement, travail, date_cs, service) VALUES (";
  91. requete << item[0] << ", "; //numéro travail -> id PRIMARY KEY
  92. if (item[1].IsSameAs("")) //n_dossier
  93. requete << "NULL, ";
  94. else
  95. requete << item[1] << ", ";
  96. requete << "\"" << item[3] << "\", " //Nom
  97. << "\"" << item[4] << "\", " //Prénom
  98. << "\"" << item[19] << "\", " //Responsable
  99. << "\"" << item[20] << "\", " //Consultant
  100. << "\"" << item[13] << "\", " //Thème
  101. << "\"" << item[7] << "\", " //Etablissement
  102. << "\"" << item[12] << "\", " //Type travail
  103. << "\"" << item[21] << "\", " //Date_cs
  104. << "\"" << item[6] << "\"" //Service
  105. << ");";
  106. rc += sqlite3_exec(db, _C(requete), NULL, NULL, NULL);
  107. //Insertion dans la table de résultats
  108. requete = "INSERT OR IGNORE INTO Result (id) VALUES (";
  109. requete << item[0]
  110. << ");";
  111. rc += sqlite3_exec(db, _C(requete), NULL, NULL, NULL);
  112. }
  113. is_first_line = false;
  114. //Annulation de l'import
  115. if (!dialog_progress.Update(progress))
  116. {
  117. wxMessageBox(_T("Aucune nouvelle donnée n'a été ajoutée"), "Attention !");
  118. sqlite3_exec(db, "ROLLBACK TO before_import;", NULL, NULL, NULL);
  119. break;
  120. }
  121. if (content[progress] == '\0')
  122. break;
  123. }while (c != '\0');
  124. file_import->Close();
  125. dialog_progress.Update(size);
  126. sqlite3_exec(db, "RELEASE before_import;", NULL, NULL, NULL);
  127. if (rc)
  128. wxMessageBox("Erreur lors de l'import", "Erreur", wxOK | wxICON_ERROR);
  129. GenerateGrid();
  130. }
  131. void class_bdd::Exporter(const wxString& filename)
  132. {
  133. wxProgressDialog dialog_progress("Export", "Export de la base...", grid_consults->GetNumberRows(), NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_ELAPSED_TIME | wxPD_REMAINING_TIME);
  134. wxFFile* file_export = new wxFFile(filename, "w");
  135. wxString line;
  136. line = _T("Travail numéro;Dossier numéro;Nom demandeur;Prénom demandeur;Service libellé;Etablissement libellé;Type travail libellé;Thème;Nom responsable;Consultant responsable;Date dernier RDV eff;Publi;Publi CHU;Consultant associé;Date de publication 1;Revue 1;Lien 1;Date de publication 2;Revue 2;Lien 2\n");
  137. file_export->Write(line, wxConvLocal);
  138. for (int i=0; i < grid_consults->GetNumberRows(); i++)
  139. {
  140. wxString id = grid_consults->GetCellValue(i,13);
  141. line="";
  142. wxString requete = "SELECT service FROM Consult WHERE id=" + id + ";";
  143. sqlite3_prepare_v2(db, _C(requete), -1, &stmt, NULL);
  144. sqlite3_step(stmt);
  145. wxString service = sqlite3_column_text(stmt,0);
  146. line << grid_consults->GetCellValue(i,13) << ";"
  147. << grid_consults->GetCellValue(i,4) << ";"
  148. << "\"" << grid_consults->GetCellValue(i,5) << "\";"
  149. << "\"" << grid_consults->GetCellValue(i,6) << "\";"
  150. << "\"" << service << "\";"
  151. << "\"" << grid_consults->GetCellValue(i,10) << "\";"
  152. << "\"" << grid_consults->GetCellValue(i,11) << "\";"
  153. << "\"" << grid_consults->GetCellValue(i,9) << "\";"
  154. << "\"" << grid_consults->GetCellValue(i,7) << "\";"
  155. << "\"" << grid_consults->GetCellValue(i,8) << "\";"
  156. << grid_consults->GetCellValue(i,12) << ";"
  157. << grid_consults->GetCellValue(i,1) << ";"
  158. << grid_consults->GetCellValue(i,2) << ";"
  159. << grid_consults->GetCellValue(i,3) << ";";
  160. wxArrayString list_publi = GetIdResult(id);
  161. for (unsigned int j=0; j < list_publi.GetCount(); j++)
  162. {
  163. if (list_publi[j].Left(1) == '@')
  164. {
  165. requete = "SELECT date_publi,revue,lien FROM Publi WHERE id=" + list_publi[j].AfterLast('@') + ";";
  166. sqlite3_prepare_v2(db, _C(requete), -1, &stmt, NULL);
  167. sqlite3_step(stmt);
  168. line << sqlite3_column_text(stmt,0) << ";" << sqlite3_column_text(stmt,1) << ";" << sqlite3_column_text(stmt,2) << ";";
  169. }
  170. }
  171. line << "\n";
  172. file_export->Write(line, wxConvLocal);
  173. dialog_progress.Update(i);
  174. }
  175. file_export->Close();
  176. }
  177. void class_bdd::GenerateGrid()
  178. {
  179. wxBeginBusyCursor();
  180. int line_nb = 0;
  181. rc = 0;
  182. stmt = NULL;
  183. if (grid_consults->GetNumberRows() != 0)
  184. grid_consults->DeleteRows(0, grid_consults->GetNumberRows()); //reset de la grille
  185. rc = sqlite3_prepare_v2(db, "SELECT * FROM Consult;", -1, &stmt, NULL); //import depuis Consult
  186. if (sqlite3_step(stmt) == SQLITE_DONE) //Si la bdd est vide
  187. {
  188. wxEndBusyCursor();
  189. wxMessageBox(_T("La base de données est vide,\nveuillez importer des données !"));
  190. return;
  191. }
  192. else
  193. sqlite3_reset(stmt); //retour à la première ligne, celle-ci étant lue juste avant pour vérifier la non vacuité
  194. while (sqlite3_step(stmt) == SQLITE_ROW)
  195. {
  196. grid_consults->AppendRows();
  197. grid_consults->SetCellValue(line_nb, 4, _itoW(sqlite3_column_int(stmt, 1))); //n_dossier
  198. for (int i=2; i<10; i++) //nom, prénom, responsable, consultant, theme, etablissement, travail, date
  199. {
  200. wxString orig = sqlite3_column_text(stmt, i);
  201. // corrections
  202. rc = sqlite3_prepare_v2(db, _C("SELECT dest FROM Correc WHERE orig=\"" + orig + "\";"), -1, &stmt_correc, NULL);
  203. if (sqlite3_step(stmt_correc) == SQLITE_DONE)
  204. grid_consults->SetCellValue(line_nb, i+3, orig);
  205. else
  206. grid_consults->SetCellValue(line_nb, i+3, sqlite3_column_text(stmt_correc, 0));
  207. sqlite3_finalize(stmt_correc);
  208. }
  209. // autocorrection prenoms
  210. wxString prenom = grid_consults->GetCellValue(line_nb, 6);
  211. if (prenom.IsSameAs("xxx", false) || prenom.IsSameAs("xx", false) || prenom.IsSameAs("zzz", false) || prenom.IsSameAs("zz", false) || prenom.IsSameAs("yy", false) || prenom.IsSameAs("xy", false))
  212. grid_consults->SetCellValue(line_nb, 6, "");
  213. // autocorrection responsables
  214. wxString responsable = grid_consults->GetCellValue(line_nb, 7);
  215. responsable.Replace("Mr. Le Pr. ", "", true);
  216. responsable.Replace("Mme Le Dr. ", "", true);
  217. responsable.Replace("Mme Le Pr. ", "", true);
  218. responsable.Replace("Mr. ", "", true);
  219. responsable.Replace("Dr. ", "", true);
  220. responsable.Replace("Dr ", "", true);
  221. responsable.Replace("Pr. ", "", true);
  222. responsable.Replace("Pr ", "", true);
  223. responsable.Replace("Mme ", "", true);
  224. responsable.Replace("Melle ", "", true);
  225. grid_consults->SetCellValue(line_nb, 7, responsable);
  226. grid_consults->SetCellValue(line_nb, 13, _itoW(sqlite3_column_int(stmt, 0))); //id, caché
  227. line_nb++;
  228. }
  229. sqlite3_finalize(stmt);
  230. line_nb = 0;
  231. sqlite3_prepare_v2(db, "SELECT * FROM Result;", -1, &stmt, NULL); //import depuis Result
  232. while (sqlite3_step(stmt) == SQLITE_ROW)
  233. {
  234. grid_consults->SetCellValue(line_nb, 0, _itoW(sqlite3_column_int(stmt, 4))); //nb_results
  235. for (int i=1; i<4; i++)
  236. grid_consults->SetCellValue(line_nb, i, _itoW(sqlite3_column_int(stmt, i))); //publi, publi_CHU, cs_associe
  237. if (sqlite3_column_int(stmt, 1))
  238. for (int i=0; i<13; i++)
  239. grid_consults->SetCellBackgroundColour(line_nb, i, *wxGREEN); //coloration des consults trouvées
  240. line_nb++;
  241. }
  242. sqlite3_finalize(stmt);
  243. grid_consults->AutoSizeColumns(false);
  244. grid_consults->AutoSizeRows(false);
  245. grid_consults->HideCol(13);
  246. wxEndBusyCursor();
  247. }
  248. void class_bdd::SetResultPubli(int row, unsigned int bitfield)
  249. {
  250. wxString id = grid_consults->GetCellValue(row,13);
  251. wxString val[3] = {"0","0","0"};
  252. //Actualisation de la grille
  253. for (int i=1; i<= 3; i++)
  254. grid_consults->SetCellValue(row,i,"0");
  255. if (bitfield & 1<<1)
  256. {
  257. grid_consults->SetCellValue(row,1,"1");
  258. val[0] = "1";
  259. }
  260. if (bitfield & 1<<2)
  261. {
  262. grid_consults->SetCellValue(row,2,"1");
  263. val[1] = "1";
  264. }
  265. if (bitfield & 1<<3)
  266. {
  267. grid_consults->SetCellValue(row,3,"1");
  268. val[2] = "1";
  269. }
  270. for (int i=0; i<13; i++)
  271. {
  272. if (bitfield & 1<<1)
  273. grid_consults->SetCellBackgroundColour(row, i, *wxGREEN);
  274. else
  275. grid_consults->SetCellBackgroundColour(row, i, grid_consults->GetDefaultCellBackgroundColour());
  276. }
  277. grid_consults->ForceRefresh();
  278. rc = 0;
  279. wxString requete = "UPDATE Result SET";
  280. requete << " publi=" << val[0]
  281. << ", publi_CHU=" << val[1]
  282. << ", cs_associe=" << val[2]
  283. << " WHERE id="
  284. << id << ";";
  285. rc = sqlite3_exec(db, _C(requete), NULL, NULL, NULL);
  286. if (rc)
  287. wxMessageBox("Erreur lors de la mise à jour de la valeur", "Erreur", wxOK | wxICON_ERROR);
  288. }
  289. wxArrayString* class_bdd::GetListCorrecs()
  290. {
  291. wxArrayString* out = new wxArrayString[2];
  292. sqlite3_prepare_v2(db, "SELECT * FROM Correc;", -1, &stmt, NULL);
  293. while (sqlite3_step(stmt) == SQLITE_ROW)
  294. {
  295. out[0].Add(sqlite3_column_text(stmt,0));
  296. out[1].Add(sqlite3_column_text(stmt,1));
  297. }
  298. sqlite3_finalize(stmt);
  299. return out;
  300. }
  301. void class_bdd::AddCorrec(const wxString& id, int col, const wxString& dest)
  302. {
  303. rc = 0;
  304. wxString requete = "SELECT * FROM Consult WHERE id=" + id + ";";
  305. sqlite3_prepare_v2(db, _C(requete), -1, &stmt, NULL);
  306. sqlite3_step(stmt);
  307. wxString orig = sqlite3_column_text(stmt, col-3);
  308. sqlite3_finalize(stmt);
  309. SetCorrec(orig, dest);
  310. }
  311. void class_bdd::SetCorrec(const wxString& orig, const wxString& dest)
  312. {
  313. wxString requete = "INSERT OR REPLACE INTO Correc VALUES (\"" + orig + "\",\"" + dest + "\");";
  314. sqlite3_exec(db, _C(requete), NULL, NULL, NULL);
  315. // Mise à jour de la grille
  316. for (int i=0; i<grid_consults->GetNumberRows(); i++)
  317. {
  318. requete = "SELECT * FROM Consult WHERE id=" + grid_consults->GetCellValue(i, 13) + ";";
  319. sqlite3_prepare_v2(db, _C(requete), -1, &stmt, NULL);
  320. sqlite3_step(stmt);
  321. for (int j=5; j<11; j++)
  322. {
  323. wxString table_orig = sqlite3_column_text(stmt, j - 3);
  324. if (table_orig == orig)
  325. grid_consults->SetCellValue(i, j, dest);
  326. }
  327. sqlite3_finalize(stmt);
  328. }
  329. // Suppression d'une correction si on revient à l'original
  330. if (dest == orig)
  331. DelCorrec(orig);
  332. }
  333. void class_bdd::DelCorrec(const wxString& orig)
  334. {
  335. sqlite3_exec(db, _C("DELETE FROM Correc WHERE orig=\"" + orig + "\";"), NULL, NULL, NULL);
  336. }
  337. int class_bdd::GetNbResults(const wxString& id)
  338. {
  339. sqlite3_prepare_v2(db, _C("SELECT nb_result FROM Result WHERE id=" + id + ";") , -1, &stmt, NULL);
  340. sqlite3_step(stmt);
  341. int out = sqlite3_column_int(stmt, 0);
  342. sqlite3_finalize(stmt);
  343. return out;
  344. }
  345. void class_bdd::SetNbResults(const wxString& id, int nb_results)
  346. {
  347. sqlite3_exec(db, _C("UPDATE Result SET nb_result=" + _itoW(nb_results) + " WHERE id=" + id + ";"), NULL, NULL, NULL);
  348. }
  349. wxArrayString class_bdd::GetIdResult(const wxString& id, bool stripped)
  350. {
  351. sqlite3_prepare_v2(db, _C("SELECT id_result FROM Result WHERE id=" + id + ";"), -1, &stmt, NULL);
  352. sqlite3_step(stmt);
  353. wxString list_id = sqlite3_column_text(stmt, 0);
  354. sqlite3_finalize(stmt);
  355. wxArrayString out;
  356. while (list_id.Length() > 0)
  357. {
  358. if (stripped)
  359. out.Add(list_id.BeforeFirst(',').AfterLast('!'));
  360. else
  361. out.Add(list_id.BeforeFirst(','));
  362. list_id = list_id.AfterFirst(',');
  363. }
  364. return out;
  365. }
  366. void class_bdd::SetIdResult(const wxString& id, wxArrayString id_results)
  367. {
  368. wxString list_id = "";
  369. int count = 0;
  370. for (unsigned int i=0; i<id_results.GetCount(); i++)
  371. {
  372. list_id += id_results[i] + ",";
  373. if (id_results[i].Left(1) != '!')
  374. count++;
  375. }
  376. list_id = list_id.BeforeLast(',');
  377. sqlite3_exec(db, _C("UPDATE Result SET id_result=\"" + list_id + "\" WHERE id=" + id + ";"), NULL, NULL, NULL);
  378. SetNbResults(id, count);
  379. }
  380. void class_bdd::AddIdResult(const wxString& id, const wxString& id_result)
  381. {
  382. sqlite3_prepare_v2(db, _C("SELECT id_result FROM Result WHERE id=" + id + ";"), -1, &stmt, NULL);
  383. sqlite3_step(stmt);
  384. wxString list_id = sqlite3_column_text(stmt, 0);
  385. sqlite3_finalize(stmt);
  386. if (list_id.Length() > 0)
  387. list_id = id_result + "," + list_id;
  388. else
  389. list_id = id_result;
  390. sqlite3_exec(db, _C("UPDATE Result SET id_result=\"" + list_id + "\" WHERE id=" + id + ";"), NULL, NULL, NULL);
  391. }
  392. bool class_bdd::IsPubli(const wxString& id)
  393. {
  394. sqlite3_prepare_v2(db, _C("SELECT * FROM Publi WHERE id=" + id + ";"), -1, &stmt, NULL);
  395. bool out = (sqlite3_step(stmt) == SQLITE_ROW);
  396. sqlite3_finalize(stmt);
  397. return out;
  398. }
  399. void class_bdd::AddPubli(wxString id, wxString title, wxString authors, wxString abstract, wxString journal, wxString link, wxString date, wxString affiliation)
  400. {
  401. title.Replace("\"", "_");
  402. abstract.Replace("\"", "_");
  403. wxString requete = "INSERT OR REPLACE INTO Publi (id, titre, auteurs, abstract, revue, lien, date_publi, affiliation) VALUES (";
  404. requete << id << ", "
  405. << "\"" << title << "\", "
  406. << "\"" << authors << "\", "
  407. << "\"" << abstract << "\", "
  408. << "\"" << journal << "\", "
  409. << "\"" << link << "\", "
  410. << "\"" << date << "\", "
  411. << "\"" << affiliation << "\");";
  412. rc = sqlite3_exec(db, _C(requete), NULL, NULL, NULL);
  413. if (rc)
  414. wxMessageBox(_itoW(rc) + "\n" + requete);
  415. }
  416. wxArrayString class_bdd::GetPublis(wxString id)
  417. {
  418. wxArrayString out;
  419. sqlite3_prepare_v2(db, _C("SELECT * FROM Publi WHERE id=" + id + ";"), -1, &stmt, NULL);
  420. sqlite3_step(stmt);
  421. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 1)));
  422. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 2)));
  423. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 3)));
  424. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 4)));
  425. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 5)));
  426. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 6)));
  427. out.Add(wxString::FromUTF8((const char*)sqlite3_column_text(stmt, 7)));
  428. return out;
  429. }