private void CompareContacts()
        {
            var mySqlContacts    = mySqlContactsGenerator.GetContacts().ToList();
            var postgresContacts = postgresContactsGenerator.GetContacts().ToList();

            // Return contacts that don't perfectly match any redacted_list contact.
            phase1ShallowCompareList = mySqlContacts.Except <Contact>(postgresContacts, new Phase1ContactComparer()).ToList();
            WriteOut.HandleMessage("Phase1: " + phase1ShallowCompareList.Count().ToString());
            // Return redacted_list contacts that link with Redmine equivalents, and don't have possible duplicates.
            phase2NonDupsReadyToSyncList = postgresContacts.Intersect <Contact>(phase1ShallowCompareList, new Phase2ContactComparer()).ToList();
            WriteOut.HandleMessage("Phase2: " + phase2NonDupsReadyToSyncList.Count().ToString());
            // Return redacted_list contacts that link with Redmine equivalents, but are possibly duplicates with varying custnums / famnums.
            phase3PossibleDupsList = postgresContacts.Intersect <Contact>(phase1ShallowCompareList, new Phase3ContactComparer()).ToList();
            // Return redacted_list contacts with combined tags taken from duplicate contacts.
            phase3PossibleDupsList = CombineTags(phase3PossibleDupsList, postgresContacts);
            WriteOut.HandleMessage("Phase3: " + phase3PossibleDupsList.Count().ToString());
            // Compare phase3 with Redmine contacts again to ensure these contacts actually need updated.
            phase4DupsReadyToSyncList = phase3PossibleDupsList.Except <Contact>(mySqlContacts, new Phase1ContactComparer()).ToList();
            WriteOut.HandleMessage("Phase4: " + phase4DupsReadyToSyncList.Count().ToString());
            // Return contacts that link with Redmine equivalents based only on email and last name being "-".
            cornerCase1ReadyToSyncList = postgresContacts.Intersect <Contact>(phase1ShallowCompareList, new CornerCase1ContactComparer()).ToList();
            WriteOut.HandleMessage("Corner1: " + cornerCase1ReadyToSyncList.Count().ToString());
            WriteOut.HandleMessage("Updated: " + (phase2NonDupsReadyToSyncList.Count() + phase4DupsReadyToSyncList.Count() + cornerCase1ReadyToSyncList.Count()).ToString());
            PrintInfo(phase2NonDupsReadyToSyncList);
            PrintInfo(phase4DupsReadyToSyncList);
            PrintInfo(cornerCase1ReadyToSyncList);
        }
 private void PrintInfo(List <Contact> contacts)
 {
     foreach (var contact in contacts)
     {
         WriteOut.HandleMessage("        Contact: " + contact.email + " | " + contact.lname + " | " + contact.tags);
     }
 }
 private void GenerateProjects()
 {
     try
     {
         contactsProjects = GetData(ReadQueryData(), ContactProject.Create);
     }
     catch (Exception e)
     {
         WriteOut.HandleMessage(e.Message);
     }
 }
 public ContactsGenPostgres()
 {
     try
     {
         connectionStringPostgres = ConfigurationManager.AppSettings["connectionStringPostgres"];
         conn = new NpgsqlConnection(connectionStringPostgres);
         GenerateContacts();
     }
     catch (Exception e)
     {
         WriteOut.HandleMessage(e.Message);
     }
 }
 private void SetupMySqlConnection()
 {
     try
     {
         connectionStringMySql = ConfigurationManager.AppSettings["connectionStringMySql"];
         conn = new MySqlConnection(connectionStringMySql);
         conn.Open();
     }
     catch (Exception e)
     {
         WriteOut.HandleMessage(e.Message);
     }
 }
 public ContactsGenMySql()
 {
     try
     {
         connectionStringMySql = ConfigurationManager.AppSettings["connectionStringMySql"];
         conn = new MySqlConnection(connectionStringMySql);
         GenerateContacts();
     }
     catch (Exception e)
     {
         WriteOut.HandleMessage(e.Message);
     }
 }
 public ContactsProjectsFromGen()
 {
     try
     {
         connectionStringMySql = ConfigurationManager.AppSettings["connectionStringMySql"];
         projectContactsFrom   = ConfigurationManager.AppSettings["contactsProjectsFrom"].Split(',');
         conn = new MySqlConnection(connectionStringMySql);
         GenerateProjects();
     }
     catch (Exception e)
     {
         WriteOut.HandleMessage(e.Message);
     }
 }
        private void AssociateContactsWithProjects()
        {
            var mySqlContacts             = mySqlContactsGenerator.GetContacts().ToList();
            var postgresContacts          = postgresContactsGenerator.GetContacts().ToList();
            var contactsToAssociatePhase1 = mySqlContacts.Intersect <Contact>(postgresContacts, new Phase1ContactComparer()).ToList();
            var contactsProjectsFromGen   = new ContactsProjectsFromGen();
            // A list of row data from table contacts_projects matching the specified project_id.
            var contactsProjectsFrom = contactsProjectsFromGen.GetContactsProjects().ToList();
            // Select from all potential contacts the contacts that match the specified 'from' project_id(s).
            var contactsToAssociatePhase2 = contactsToAssociatePhase1.Select(p1 => p1).Where(p1 => contactsProjectsFrom.Select(cF => cF.cid).Contains(p1.id));
            // Comma delimmited project-to IDs, set in App.config.
            var contactsProjectsTo = ConfigurationManager.AppSettings["contactsProjectsTo"].Split(',');
            // A list of commands that will insert the contact associations.
            var cmdList = new List <string>();
            var insertContactsProjectsCmd = new StringBuilder();

            foreach (var contact in contactsToAssociatePhase2)
            {
                foreach (var pid in contactsProjectsTo)
                {
                    // This command only inserts a new record if one does not already exist.
                    insertContactsProjectsCmd.AppendFormat("INSERT INTO contacts_projects (project_id, contact_id) SELECT * FROM (SELECT {0}, {1}) AS tmp WHERE NOT EXISTS (SELECT project_id, contact_id FROM contacts_projects WHERE project_id={0} AND contact_id={1}) LIMIT 1;",
                                                           pid, contact.id);
                    cmdList.Add(insertContactsProjectsCmd.ToString());
                    insertContactsProjectsCmd.Clear();
                }
            }
            SetupMySqlConnection();
            int counter = 0;

            insertContactsProjectsCmd.Clear();
            // Concatenate every 10 insert command strings and run the command.
            foreach (var cmdString in cmdList)
            {
                if (counter < 10)
                {
                    insertContactsProjectsCmd.Append(cmdString);
                    counter++;
                }
                else
                {
                    InsertContactAssociations(insertContactsProjectsCmd.ToString());
                    insertContactsProjectsCmd.Clear();
                    insertContactsProjectsCmd.Append(cmdString);
                    counter = 1;
                }
            }
            WriteOut.HandleMessage("Associated: " + cmdList.Count().ToString());
            conn.Close();
        }
 public Sync()
 {
     try
     {
         Stopwatch stopWatch = new Stopwatch();
         stopWatch.Start();
         WriteOut.HandleMessage("START");
         // A switch for associating contacts.
         int associateSwitch = Int32.Parse(ConfigurationManager.AppSettings["associateSwitch"]);
         combinedTags = new Dictionary <string, string>();
         GenerateContacts();
         CompareContacts();
         if (phase2NonDupsReadyToSyncList.Count() >= 1)
         {
             // Sync nonduplicate contacts.
             SyncContacts(1);
         }
         if (phase4DupsReadyToSyncList.Count() >= 1)
         {
             // Sync duplicate-combined contacts.
             SyncContacts(2);
         }
         if (cornerCase1ReadyToSyncList.Count() >= 1)
         {
             // Sync corner case contacts.
             SyncContacts(3);
         }
         if (associateSwitch == 1)
         {
             // Generate contacts a second time so they are up-to-date for the associating process.
             GenerateContacts();
             AssociateContactsWithProjects();
         }
         stopWatch.Stop();
         WriteOut.HandleMessage("RunTime: " + String.Format("{0:00}:{1:00}.{2:00}", stopWatch.Elapsed.Minutes, stopWatch.Elapsed.Seconds, stopWatch.Elapsed.Milliseconds));
         WriteOut.HandleMessage("END");
     }
     catch (Exception e)
     {
         // Get stack trace for the exception with source file information.
         var st = new StackTrace(e, true);
         WriteOut.HandleMessage("Error: " + e.Message);
         WriteOut.HandleMessage("StackTrace: " + st);
     }
 }