public void CreateCaseSyncFileStart(Epi.ImportExport.Filters.RowFilters filters, Epi.RecordProcessingScope recordProcessingScope) { if (IsWaitingOnOtherClients) { return; } if (String.IsNullOrEmpty(SyncFilePath.Trim())) { throw new InvalidOperationException(); } var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); bool includeCases = IncludeCasesAndContacts || IncludeCasesOnly; bool includeCaseExposures = true; bool includeContacts = IncludeCasesAndContacts; bool deIdentifyData = DeIdentifyData; #region Remove extraneous data int rows = 0; OverallSyncStatus = "Deleting extraneous page table rows..."; IDbDriver db = _project.CollectedData.GetDatabase(); foreach (View form in _project.Views) { foreach (Page page in form.Pages) { Query deleteQuery = db.CreateQuery("DELETE FROM " + form.Name + " WHERE GlobalRecordId NOT IN (SELECT GlobalRecordId FROM " + page.TableName + ")"); rows = db.ExecuteNonQuery(deleteQuery); if (rows > 0) { // report ?? } Query pageDeleteQuery = db.CreateQuery("DELETE FROM " + page.TableName + " WHERE GlobalRecordId NOT IN (SELECT GlobalRecordId FROM " + form.Name + ")"); rows = db.ExecuteNonQuery(deleteQuery); if (rows > 0) { // report ?? } } } Query linksDeleteQuery = db.CreateQuery("DELETE FROM metaLinks WHERE ToViewId = @ToViewId AND ToRecordGuid NOT IN (SELECT GlobalRecordId FROM " + ContactForm.TableName + ")"); linksDeleteQuery.Parameters.Add(new QueryParameter("@ToViewId", DbType.Int32, ContactFormId)); rows = db.ExecuteNonQuery(linksDeleteQuery); if (db.TableExists("metaHistory")) { Query historyDeleteQuery = db.CreateQuery("DELETE FROM metaHistory WHERE ContactGUID NOT IN (SELECT GlobalRecordId FROM " + ContactForm.TableName + ")"); rows = db.ExecuteNonQuery(historyDeleteQuery); } #endregion // Remove extraneous data RecordsExported = String.Empty; IsDataSyncing = true; IsShowingExportProgress = true; var doc = new XmlDocument { XmlResolver = null }; SendMessageForAwaitAll(); Task.Factory.StartNew( () => { doc = CreateCaseSyncFile(includeCases, includeCaseExposures, includeContacts, filters, deIdentifyData, recordProcessingScope); }, System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default).ContinueWith( delegate { try { if (!String.IsNullOrEmpty(doc.InnerText)) { string compressedText = Epi.ImportExport.ImportExportHelper.Zip(doc.OuterXml); compressedText = "[[EPIINFO7_VHF_CASE_SYNC_FILE__0937]]" + compressedText; Epi.Configuration.EncryptStringToFile(compressedText, SyncFilePath, "vQ@6L'<J3?)~5=vQnwh(2ic;>.<=dknF&/TZ4Uu!$78", "", "", 1000); } } catch (Exception) { // do nothing... if the XML is invalid, we should have already alerted the user in a different method } finally { SendMessageForUnAwaitAll(); } TaskbarProgressState = System.Windows.Shell.TaskbarItemProgressState.None; TaskbarProgressValue = 0; ProgressValue = 0; IsDataSyncing = false; stopwatch.Stop(); SyncStatus = String.Empty; OverallSyncStatus = "Finished exporting data to sync file. Elapsed time: " + stopwatch.Elapsed.TotalMinutes.ToString("F1") + " minutes."; }, TaskScheduler.FromCurrentSynchronizationContext()); }
private XmlDocument CreateCaseSyncFile(bool includeCases, bool includeCaseExposures, bool includeContacts, Epi.ImportExport.Filters.RowFilters filters, bool deIdentifyData, Epi.RecordProcessingScope recordProcessingScope) { TaskbarProgressValue = 0; TaskbarProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal; ProgressValue = 0; _increment = 0.25; if (includeCaseExposures && includeContacts) { _increment = 0.25; } else if (includeCaseExposures && !includeContacts) { _increment = 0.34; } else if (!includeCaseExposures && !includeContacts) { _increment = 0.5; } IDbDriver database = _project.CollectedData.GetDatabase(); //#region Repair page tables //RemoveExtraneousPageTableRecordsCommand.Execute(null); //#endregion // Repair page tables #region Case and Lab Data //var packager = new ContactTracing.ExportView.XmlSqlDataPackager(CaseForm, "sync") //new Epi.ImportExport.ProjectPackagers.XmlDataPackager(CaseForm, "sync") var packager = new Epi.ImportExport.ProjectPackagers.XmlDataPackager(CaseForm, "sync") { RecordProcessingScope = recordProcessingScope }; packager.StatusChanged += unpackager_StatusChanged; packager.UpdateProgress += unpackager_UpdateProgress; if (filters == null) { filters = new Epi.ImportExport.Filters.RowFilters(database, Epi.ImportExport.Filters.ConditionJoinTypes.And); } if (includeCases == false) { // filter out all cases var tfc = new Epi.ImportExport.TextRowFilterCondition("[EpiCaseDef] = @EpiCaseDef", "EpiCaseDef", "@EpiCaseDef", "1000") { Description = "EpiCaseDef is equal to 1000" }; filters.Add(tfc); } DateTime dateValue = DateTime.MinValue; DateTime today = DateTime.Now; TimeSpan ts = new TimeSpan(int.Parse(Days), 0, 0, 0); DateTime nDaysAgo = today - ts; dateValue = nDaysAgo; var daysAgoFilter = new Epi.ImportExport.DateRowFilterCondition("LastSaveTime >= @LastSaveTime", "LastSaveTime", "@LastSaveTime", dateValue); filters.Add(daysAgoFilter); packager.Filters = new Dictionary <string, Epi.ImportExport.Filters.RowFilters> { { "CaseInformationForm", filters } }; if (deIdentifyData) { if (!IsCountryUS) { packager.FieldsToNull.Add(CaseForm.Name, new List <string> { "Surname", "OtherNames", "PhoneNumber", "PhoneOwner", "HeadHouse", "ContactName1", "ContactName2", "ContactName3", "FuneralName1", "FuneralName2", "HospitalBeforeIllPatient", "TradHealerName", "InterviewerName", "InterviewerPhone", "InterviwerEmail", "ProxyName" }); packager.FieldsToNull.Add(LabForm.Name, new List <string> { "SurnameLab", "OtherNameLab" }); } else { packager.FieldsToNull.Add(CaseForm.Name, new List <string> { "Surname", "OtherNames", "PhoneNumber", "PhoneOwner", "HeadHouse", "ContactName1", "ContactName2", "ContactName3", "FuneralName1", "FuneralName2", "HospitalBeforeIllPatient", "TradHealerName", "InterviewerName", "InterviewerPhone", "InterviwerEmail", "ProxyName", "DOB", "Email", "AddressRes", "AddressOnset", "ProxyPhone", "ProxyEmail" }); packager.FieldsToNull.Add(LabForm.Name, new List <string> { "SurnameLab", "OtherNameLab", "PersonLabSubmit", "PhoneLabSubmit", "EmailLabSubmit" }); } } packager.IncludeNullFieldData = false; var doc = new XmlDocument { XmlResolver = null }; bool failed = false; try { OverallSyncStatus = "Packaging case records..."; doc = packager.PackageForm(); TaskbarProgressValue = TaskbarProgressValue + _increment; OverallSyncStatus = "Finished packaging case records"; if (packager.ExportInfo.RecordsPackaged.ContainsKey(LabForm)) { RecordsExported = "Exported: " + RecordsExported + packager.ExportInfo.RecordsPackaged[CaseForm].ToString() + " cases, " + packager.ExportInfo.RecordsPackaged[LabForm].ToString() + " lab results"; } else { RecordsExported = "Exported: " + RecordsExported + packager.ExportInfo.TotalRecordsPackaged.ToString() + " cases"; } } catch (Exception ex) { if (SyncProblemsDetected != null) { SyncProblemsDetected(ex, new EventArgs()); } failed = true; } finally { packager.StatusChanged -= unpackager_StatusChanged; packager.UpdateProgress -= unpackager_UpdateProgress; } if (failed) { return(doc); } #endregion // Case and Lab Data #region Contact Data if (includeContacts) { OverallSyncStatus = "Packaging contact records..."; //packager = new ContactTracing.ExportView.XmlSqlDataPackager(ContactForm, "sync") //new Epi.ImportExport.ProjectPackagers.XmlSqlDataPackager(ContactForm, "sync"); packager = new Epi.ImportExport.ProjectPackagers.XmlDataPackager(ContactForm, "sync") { RecordProcessingScope = recordProcessingScope }; packager.StatusChanged += unpackager_StatusChanged; packager.UpdateProgress += unpackager_UpdateProgress; packager.RecordProcessingScope = recordProcessingScope; filters = new Epi.ImportExport.Filters.RowFilters(database, Epi.ImportExport.Filters.ConditionJoinTypes.And); daysAgoFilter = new Epi.ImportExport.DateRowFilterCondition("LastSaveTime >= @LastSaveTime", "LastSaveTime", "@LastSaveTime", dateValue); filters.Add(daysAgoFilter); packager.Filters = new Dictionary <string, Epi.ImportExport.Filters.RowFilters> { { ContactForm.Name, filters } }; if (deIdentifyData) { if (!IsCountryUS) { packager.FieldsToNull.Add(ContactForm.Name, new List <string> { "ContactSurname", "ContactOtherNames", "ContactHeadHouse", "ContactPhone", "LC1" }); } else { packager.FieldsToNull.Add(ContactForm.Name, new List <string> { "ContactSurname", "ContactOtherNames", "ContactHeadHouse", "ContactPhone", "LC1", "ContactDOB", "ContactAddress", "ContactEmail" }); } } try { XmlDocument contactDoc = packager.PackageForm(); RecordsExported = RecordsExported + ", " + packager.ExportInfo.TotalRecordsPackaged.ToString() + " contacts"; XmlNodeList xnList = contactDoc.SelectNodes("/DataPackage/Form"); if (IsCountryUS) { foreach (XmlNode node in contactDoc.GetElementsByTagName("FieldInfo")) { if (node.Attributes[0].Value == "AdminOverride") { node.ParentNode.RemoveChild(node); break; } } } if (xnList.Count == 1) { XmlNode nodeToCopy = doc.ImportNode(contactDoc.SelectSingleNode("/DataPackage/Form"), true); // note: target XmlNode parentNode = doc.SelectSingleNode("/DataPackage"); parentNode.AppendChild(nodeToCopy); //doc.Save(@"C:\Temp\ContactTest.xml"); } } catch (Exception ex) { //if (SyncProblemsDetected != null) //{ // SyncProblemsDetected(ex, new EventArgs()); //} // TODO: Re-work this } finally { packager.StatusChanged -= unpackager_StatusChanged; packager.UpdateProgress -= unpackager_UpdateProgress; } } TaskbarProgressValue = TaskbarProgressValue + _increment; OverallSyncStatus = "Finished packaging contact records"; #endregion // Contact Data #region Link Data if (includeCaseExposures || includeContacts) { OverallSyncStatus = "Packaging relationship records..."; #region metaLinks table XmlElement links = doc.CreateElement("Links"); Query selectQuery = database.CreateQuery("SELECT * FROM [metaLinks] ORDER BY [LastContactDate] DESC"); DataTable linksTable = database.Select(selectQuery); foreach (DataRow row in linksTable.Rows) { XmlElement link = doc.CreateElement("Link"); var toViewId = (int)row["ToViewId"]; var fromViewId = (int)row["FromViewId"]; if (includeCaseExposures && toViewId == CaseFormId && fromViewId == CaseFormId) { // we have a case-to-case link, add it foreach (DataColumn dc in linksTable.Columns) { XmlElement element = doc.CreateElement(dc.ColumnName); if (row[dc] != DBNull.Value) { if (row[dc] is DateTime || dc.ColumnName.Equals("LastContactDate", StringComparison.OrdinalIgnoreCase)) { var dt = (DateTime)row[dc]; element.InnerText = dt.Ticks.ToString(); } else { element.InnerText = row[dc].ToString(); } } else { element.InnerText = String.Empty; } //if (!String.IsNullOrEmpty(element.InnerText) || !element.Name.StartsWith("Day", StringComparison.OrdinalIgnoreCase)) //{ link.AppendChild(element); //} } } if (includeContacts && toViewId == ContactFormId && fromViewId == CaseFormId) { // we have a case-to-contact link, add it foreach (DataColumn dc in linksTable.Columns) { XmlElement element = doc.CreateElement(dc.ColumnName); if (row[dc] != DBNull.Value) { if (row[dc] is DateTime || dc.ColumnName.Equals("LastContactDate", StringComparison.OrdinalIgnoreCase)) { var dt = (DateTime)row[dc]; element.InnerText = dt.Ticks.ToString(); } else { element.InnerText = row[dc].ToString(); } } else { element.InnerText = String.Empty; } //if (!String.IsNullOrEmpty(element.InnerText) || !element.Name.StartsWith("Day", StringComparison.OrdinalIgnoreCase)) //{ link.AppendChild(element); //} } } links.AppendChild(link); } doc.ChildNodes[0].AppendChild(links); #endregion // metaLinks table TaskbarProgressValue = TaskbarProgressValue + _increment; RecordsExported = RecordsExported + ", " + linksTable.Rows.Count.ToString() + " relationships"; if (includeContacts) { if (database.TableExists("metaHistory")) { OverallSyncStatus = "Packaging daily follow-up records..."; #region metaHistory table XmlElement followUps = doc.CreateElement("ContactFollowUps"); selectQuery = database.CreateQuery("SELECT * FROM [metaHistory] ORDER BY [ContactGUID] DESC, [FollowUpDate] DESC"); DataTable followUpsTable = database.Select(selectQuery); foreach (DataRow row in followUpsTable.Rows) { XmlElement followUp = doc.CreateElement("ContactFollowUp"); XmlElement guid = doc.CreateElement("ContactGUID"); guid.InnerText = row["ContactGUID"].ToString(); followUp.AppendChild(guid); CultureInfo format = CultureInfo.InvariantCulture; XmlElement fuDate = doc.CreateElement("FollowUpDate"); fuDate.InnerText = Convert.ToDateTime(row["FollowUpDate"]).ToString(format.DateTimeFormat.ShortDatePattern); followUp.AppendChild(fuDate); XmlElement statusOnDate = doc.CreateElement("StatusOnDate"); statusOnDate.InnerText = row["StatusOnDate"].ToString(); followUp.AppendChild(statusOnDate); XmlElement note = doc.CreateElement("Note"); note.InnerText = row["Note"].ToString(); followUp.AppendChild(note); if (row.Table.Columns.Contains("Temp1")) { XmlElement temp1 = doc.CreateElement("Temp1"); if (row["Temp1"] != DBNull.Value) { temp1.InnerText = Convert.ToDouble(row["Temp1"]).ToString(System.Globalization.CultureInfo.InvariantCulture); } followUp.AppendChild(temp1); XmlElement temp2 = doc.CreateElement("Temp2"); if (row["Temp2"] != DBNull.Value) { temp2.InnerText = Convert.ToDouble(row["Temp2"]).ToString(System.Globalization.CultureInfo.InvariantCulture); } followUp.AppendChild(temp2); } followUps.AppendChild(followUp); } #endregion // metaHistory table doc.ChildNodes[0].AppendChild(followUps); TaskbarProgressValue = TaskbarProgressValue + _increment; RecordsExported = RecordsExported + ", " + followUpsTable.Rows.Count.ToString() + " follow-ups"; } } } #endregion // Link Data return(doc); }