Example #1
0
 private void butRun_Click(object sender, EventArgs e)
 {
     if (comboDbs.SelectedIndex == -1)
     {
         MsgBox.Show(this, "Please select a backup database first.");
         return;
     }
     //make sure it's not this database
     if (comboDbs.SelectedItem.ToString() == MiscData.GetCurrentDatabase())
     {
         MsgBox.Show(this, "Please choose a database other than the current database.");
         return;
     }
     //make sure it's from before March 17th.
     //if(!DatabaseMaintenance.DatabaseIsOlderThanMarchSeventeenth(comboDbs.SelectedItem.ToString())){
     //	MsgBox.Show(this,"The backup database must be older than March 17, 2010.");
     //	return;
     //}
     Cursor                 = Cursors.WaitCursor;
     textResults.Text       = "";
     duplicateClaimProcInfo = DatabaseMaintenances.GetDuplicateClaimProcs();
     if (duplicateClaimProcInfo == "")
     {
         textResults.Text += "Duplicate claim payments: None found.  Database OK.\r\n\r\n";
     }
     else
     {
         textResults.Text += duplicateClaimProcInfo;
     }
     duplicateSuppInfo = DatabaseMaintenances.GetDuplicateSupplementalPayments();
     if (duplicateSuppInfo == "")
     {
         textResults.Text += "Duplicate supplemental payments: None found.  Database OK.\r\n\r\n";
     }
     else
     {
         textResults.Text += duplicateSuppInfo;
     }
     missingSuppInfo = DatabaseMaintenances.GetMissingClaimProcs(comboDbs.SelectedItem.ToString());
     if (missingSuppInfo == "")
     {
         textResults.Text += "Missing claim payments: None found.  Database OK.";
     }
     else
     {
         textResults.Text += missingSuppInfo;
     }
     Cursor = Cursors.Default;
 }
Example #2
0
        private void butSynch_Click(object sender, EventArgs e)
        {
            if (textUsername.Text == "")
            {
                MsgBox.Show(this, "Please enter a username first.");
                return;
            }
            if (ReplicationServers.Listt.Count == 0)
            {
                MsgBox.Show(this, "Please add at servers to the list first");
                return;
            }
            Cursor = Cursors.WaitCursor;
            string currentDatabaseName = MiscData.GetCurrentDatabase();

            for (int i = 0; i < ReplicationServers.Listt.Count; i++)
            {
                string         compName = ReplicationServers.Listt[i].Descript;
                DataConnection dc       = new DataConnection();
                try {
                    //try {
                    dc.SetDb(compName, currentDatabaseName, textUsername.Text, textPassword.Text, "", "", DataConnection.DBtype);
                    //}
                    //catch(MySql.Data.MySqlClient.MySqlException ex) {
                    //	if(ex.Number==1042) {//The error 1042 is issued when the connection could not be made.
                    //		throw ex;//Pass the exception along.
                    //	}
                    //	DataConnection.cmd.Connection.Close();
                    //}
                    //Connection is considered to be successfull at this point. Now restart the slave process to force replication.
                    string    command     = "SLAVE STOP; START SLAVE; SHOW SLAVE STATUS;";
                    DataTable slaveStatus = dc.GetTable(command);
                    //Wait for the slave process to become active again.
                    for (int j = 0; j < 40 && slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes"; j++)
                    {
                        Thread.Sleep(1000);
                        command     = "SHOW SLAVE STATUS";
                        slaveStatus = dc.GetTable(command);
                    }
                    if (slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes")
                    {
                        throw new Exception("Slave IO is not running on computer " + compName);
                    }
                    if (slaveStatus.Rows[0]["Slave_SQL_Running"].ToString().ToLower() != "yes")
                    {
                        throw new Exception("Slave SQL is not running on computer " + compName);
                    }
                    //Wait for replication to complete.
                    while (slaveStatus.Rows[0]["Slave_IO_State"].ToString().ToLower() != "waiting for master to send event" ||
                           slaveStatus.Rows[0]["Seconds_Behind_Master"].ToString() != "0")
                    {
                        slaveStatus = dc.GetTable(command);
                    }
                }
                catch (Exception ex) {
                    Cursor = Cursors.Default;
                    MessageBox.Show(Lan.g(this, "Error forcing replication on computer") + " " + compName + ": " + ex.Message);
                    return;                    //Cancel operation.
                }
            }
            Cursor = Cursors.Default;
            MessageBox.Show(Lan.g(this, "Database synch completed successfully."));
        }
        private void butSynch_Click(object sender, EventArgs e)
        {
            if (textUsername.Text == "")
            {
                MsgBox.Show(this, "Please enter a username first.");
                return;
            }
            if (_listReplicationServers.Count == 0)
            {
                MsgBox.Show(this, "Please add at servers to the list first.");
                return;
            }
            Cursor = Cursors.WaitCursor;
            string         databaseNameOriginal = MiscData.GetCurrentDatabase();
            string         compNameOriginal     = DataConnection.GetServerName();
            DataConnection dc;
            bool           isReplicationSucessfull = true;

            for (int i = 0; i < _listReplicationServers.Count; i++)
            {
                string compName = _listReplicationServers[i].Descript;
                dc = new DataConnection();
                try {
                    dc.SetDb(compName, databaseNameOriginal, textUsername.Text, textPassword.Text, "", "", DataConnection.DBtype);
                    //Connection is considered to be successfull at this point. Now restart the slave process to force replication.
                    string    command     = "STOP SLAVE; START SLAVE; SHOW SLAVE STATUS;";
                    DataTable slaveStatus = dc.GetTable(command);
                    //Wait for the slave process to become active again.
                    for (int j = 0; j < 40 && slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes"; j++)
                    {
                        Thread.Sleep(1000);
                        command     = "SHOW SLAVE STATUS";
                        slaveStatus = dc.GetTable(command);
                    }
                    if (slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes")
                    {
                        throw new ApplicationException(Lan.g(this, "Slave IO is not running on server") + " " + compName);
                    }
                    if (slaveStatus.Rows[0]["Slave_SQL_Running"].ToString().ToLower() != "yes")
                    {
                        throw new ApplicationException(Lan.g(this, "Slave SQL is not running on server") + " " + compName);
                    }
                    //Wait for replication to complete.
                    while (slaveStatus.Rows[0]["Slave_IO_State"].ToString().ToLower() != "waiting for master to send event" ||
                           slaveStatus.Rows[0]["Seconds_Behind_Master"].ToString() != "0")
                    {
                        slaveStatus = dc.GetTable(command);
                    }
                }
                catch (Exception ex) {
                    Cursor = Cursors.Default;
                    MessageBox.Show(Lan.g(this, "Error forcing synch on server") + " " + compName + ": " + ex.Message);
                    isReplicationSucessfull = false;
                    break;                    //Cancel operation.
                }
            }
            if (isReplicationSucessfull)
            {
                Cursor = Cursors.Default;
                MessageBox.Show(Lan.g(this, "Database synch completed successfully."));
            }
            //Do not leave this function without connecting back to original database, or closing program.
            //At this point we are still connected to the last replication server in the list, try to connect back up to the original database.
            bool isReconnectSuccessful = false;

            while (!isReconnectSuccessful)
            {
                try {
                    //Reconnect back to original database.
                    dc = new DataConnection();
                    dc.SetDb(compNameOriginal, databaseNameOriginal, textUsername.Text, textPassword.Text, "", "", DataConnection.DBtype);
                    isReconnectSuccessful = true;                  //No exception thrown, leave while loop.
                }
                catch (Exception ex) {
                    if (MessageBox.Show(Lan.g(this, "Error reconnecting to server") + " " + compNameOriginal + ": " + ex.Message + "\r\n" +
                                        Lan.g(this, "Would you like to retry?  Cancel will close the program."), "", MessageBoxButtons.OKCancel) != DialogResult.OK)
                    {
                        FormOpenDental.S_ProcessKillCommand();
                    }
                }
            }
        }
Example #4
0
        ///<summary>Called in two places.  Once from FormOpenDental.PrefsStartup, and also from FormBackups after a restore.</summary>
        public static bool CheckProgramVersion()
        {
            if (PrefC.GetBool(PrefName.UpdateWindowShowsClassicView))
            {
                return(CheckProgramVersionClassic());
            }
            Version storedVersion  = new Version(PrefC.GetString(PrefName.ProgramVersion));
            Version currentVersion = new Version(Application.ProductVersion);
            string  database       = "";

            //string command="";
            if (DataConnection.DBtype == DatabaseType.MySql)
            {
                database = MiscData.GetCurrentDatabase();
            }
            if (storedVersion < currentVersion)
            {
                //There are two different situations where this might happen.
                if (PrefC.GetString(PrefName.UpdateInProgressOnComputerName) == "")              //1. Just performed an update from this workstation on another database.
                //This is very common for admins when viewing slighly older databases.
                //There should be no annoying behavior here.  So do nothing.
                {
                                        #if !DEBUG
                    //Excluding this in debug allows us to view slightly older databases without accidentally altering them.
                    Prefs.UpdateString(PrefName.ProgramVersion, currentVersion.ToString());
                    Cache.Refresh(InvalidType.Prefs);
                                        #endif
                    return(true);
                }
                //and 2a. Just performed an update from this workstation on this database.
                //or 2b. Just performed an update from this workstation for multiple databases.
                //In both 2a and 2b, we already downloaded Setup file to correct location for this db, so skip 1 above.
                //This computer just performed an update, but none of the other computers has updated yet.
                //So attempt to stash all files that are in the Application directory.
                if (!CopyFromHereToUpdateFiles(currentVersion))
                {
                    Application.Exit();
                    return(false);
                }
                Prefs.UpdateString(PrefName.ProgramVersion, currentVersion.ToString());
                Prefs.UpdateString(PrefName.UpdateInProgressOnComputerName, "");               //now, other workstations will be allowed to update.
                Cache.Refresh(InvalidType.Prefs);
            }
            if (storedVersion > currentVersion)
            {
                //This is the update sequence for both a direct workstation, and for a ClientWeb workstation.
                if (!PrefC.UsingAtoZfolder)                //Not using image path.
                //this does not bypass checking the RegistrationKey because that's the only way to get the UpdateCode.
                //perform program update automatically.
                {
                    DownloadAndRunSetup(storedVersion, currentVersion);
                    Application.Exit();
                    return(false);
                }
                string folderUpdate = ODFileUtils.CombinePaths(ImageStore.GetPreferredAtoZpath(), "UpdateFiles");
                //look at the manifest to see if it's the version we need
                string manifestVersion = "";
                try {
                    manifestVersion = File.ReadAllText(ODFileUtils.CombinePaths(folderUpdate, "Manifest.txt"));
                }
                catch {
                    //fail silently
                }
                if (manifestVersion != storedVersion.ToString(3))               //manifest version is wrong
                //No point trying the Setup.exe because that's probably wrong too.
                //Just go straight to downloading and running the Setup.exe.
                {
                    string manpath = ODFileUtils.CombinePaths(folderUpdate, "Manifest.txt");
                    if (MessageBox.Show(Lan.g("Prefs", "The expected version information was not found in this file: ") + manpath + ".  "
                                        + Lan.g("Prefs", "There is probably a permission issue on that folder which should be fixed. ")
                                        + "\r\n\r\n" + Lan.g("Prefs", "The suggested solution is to return to the computer where the update was just run.  Go to Help | Update | Setup, and click the Recopy button.")
                                        + "\r\n\r\n" + Lan.g("Prefs", "If, instead, you click OK in this window, then a fresh Setup file will be downloaded and run."),
                                        "", MessageBoxButtons.OKCancel) != DialogResult.OK)     //they don't want to download again.
                    {
                        Application.Exit();
                        return(false);
                    }
                    DownloadAndRunSetup(storedVersion, currentVersion);
                    Application.Exit();
                    return(false);
                }
                //manifest version matches
                if (MessageBox.Show(Lan.g("Prefs", "Files will now be copied.") + "\r\n"
                                    + Lan.g("Prefs", "Workstation version will be updated from ") + currentVersion.ToString(3)
                                    + Lan.g("Prefs", " to ") + storedVersion.ToString(3),
                                    "", MessageBoxButtons.OKCancel)
                    != DialogResult.OK)                   //they don't want to update for some reason.
                {
                    Application.Exit();
                    return(false);
                }
                string tempDir = Path.GetTempPath();
                //copy UpdateFileCopier.exe to the temp directory
                File.Copy(ODFileUtils.CombinePaths(folderUpdate, "UpdateFileCopier.exe"), //source
                          ODFileUtils.CombinePaths(tempDir, "UpdateFileCopier.exe"),      //dest
                          true);                                                          //overwrite
                //wait a moment to make sure the file was copied
                Thread.Sleep(500);
                //launch UpdateFileCopier to copy all files to here.
                int    processId = Process.GetCurrentProcess().Id;
                string appDir    = Application.StartupPath;
                Process.Start(ODFileUtils.CombinePaths(tempDir, "UpdateFileCopier.exe"),
                              "\"" + folderUpdate + "\""   //pass the source directory to the file copier.
                              + " " + processId.ToString() //and the processId of Open Dental.
                              + " \"" + appDir + "\"");    //and the directory where OD is running
                Application.Exit();                        //always exits, whether launch of setup worked or not
                return(false);
            }
            return(true);
        }
Example #5
0
        ///<summary>Essentially no changes have been made to this since version 6.5.</summary>
        private static bool CheckProgramVersionClassic()
        {
            Version storedVersion  = new Version(PrefC.GetString(PrefName.ProgramVersion));
            Version currentVersion = new Version(Application.ProductVersion);
            string  database       = MiscData.GetCurrentDatabase();

            if (storedVersion < currentVersion)
            {
                Prefs.UpdateString(PrefName.ProgramVersion, currentVersion.ToString());
                Cache.Refresh(InvalidType.Prefs);
            }
            if (storedVersion > currentVersion)
            {
                if (PrefC.UsingAtoZfolder)
                {
                    string setupBinPath = ODFileUtils.CombinePaths(ImageStore.GetPreferredAtoZpath(), "Setup.exe");
                    if (File.Exists(setupBinPath))
                    {
                        if (MessageBox.Show("You are attempting to run version " + currentVersion.ToString(3) + ",\r\n"
                                            + "But the database " + database + "\r\n"
                                            + "is already using version " + storedVersion.ToString(3) + ".\r\n"
                                            + "A newer version must have already been installed on at least one computer.\r\n"
                                            + "The setup program stored in your A to Z folder will now be launched.\r\n"
                                            + "Or, if you hit Cancel, then you will have the option to download again."
                                            , "", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                        {
                            if (MessageBox.Show("Download again?", "", MessageBoxButtons.OKCancel)
                                == DialogResult.OK)
                            {
                                FormUpdate FormU = new FormUpdate();
                                FormU.ShowDialog();
                            }
                            Application.Exit();
                            return(false);
                        }
                        try {
                            Process.Start(setupBinPath);
                        }
                        catch {
                            MessageBox.Show("Could not launch Setup.exe");
                        }
                    }
                    else if (MessageBox.Show("A newer version has been installed on at least one computer," +
                                             "but Setup.exe could not be found in any of the following paths: " +
                                             ImageStore.GetPreferredAtoZpath() + ".  Download again?", "", MessageBoxButtons.OKCancel) == DialogResult.OK)
                    {
                        FormUpdate FormU = new FormUpdate();
                        FormU.ShowDialog();
                    }
                }
                else                  //Not using image path.
                                      //perform program update automatically.
                {
                    string patchName       = "Setup.exe";
                    string updateUri       = PrefC.GetString(PrefName.UpdateWebsitePath);
                    string updateCode      = PrefC.GetString(PrefName.UpdateCode);
                    string updateInfoMajor = "";
                    string updateInfoMinor = "";
                    if (FormUpdate.ShouldDownloadUpdate(updateUri, updateCode, out updateInfoMajor, out updateInfoMinor))
                    {
                        if (MessageBox.Show(updateInfoMajor + Lan.g("Prefs", "Perform program update now?"), "",
                                            MessageBoxButtons.YesNo) == DialogResult.Yes)
                        {
                            string tempFile = ODFileUtils.CombinePaths(Path.GetTempPath(), patchName);       //Resort to a more common temp file name.
                            FormUpdate.DownloadInstallPatchFromURI(updateUri + updateCode + "/" + patchName, //Source URI
                                                                   tempFile, true, true, null);              //Local destination file.
                            File.Delete(tempFile);                                                           //Cleanup install file.
                        }
                    }
                }
                Application.Exit();                //always exits, whether launch of setup worked or not
                return(false);
            }
            return(true);
        }
Example #6
0
        private void butRestore_Click(object sender, System.EventArgs e)
        {
            if (textBackupRestoreFromPath.Text != "" && !textBackupRestoreFromPath.Text.EndsWith("" + Path.DirectorySeparatorChar))
            {
                MessageBox.Show(Lan.g(this, "Paths must end with ") + Path.DirectorySeparatorChar + ".");
                return;
            }
            if (textBackupRestoreToPath.Text != "" && !textBackupRestoreToPath.Text.EndsWith("" + Path.DirectorySeparatorChar))
            {
                MessageBox.Show(Lan.g(this, "Paths must end with ") + Path.DirectorySeparatorChar + ".");
                return;
            }
            if (ShouldUseAtoZFolder())
            {
                if (textBackupRestoreAtoZToPath.Text != "" && !textBackupRestoreAtoZToPath.Text.EndsWith("" + Path.DirectorySeparatorChar))
                {
                    MessageBox.Show(Lan.g(this, "Paths must end with ") + Path.DirectorySeparatorChar + ".");
                    return;
                }
            }
            if (Environment.OSVersion.Platform != PlatformID.Unix)
            {
                //dmg This check will not work on Linux, because mapped drives exist as regular (mounted) paths. Perhaps there
                //is another way to check for this on Linux.
                if (textBackupRestoreToPath.Text != "" && textBackupRestoreToPath.Text.StartsWith("" + Path.DirectorySeparatorChar))
                {
                    MsgBox.Show(this, "The restore database TO folder must be on this computer.");
                    return;
                }
            }
            //pointless to save defaults
            string dbName = MiscData.GetCurrentDatabase();

            if (InnoDb.HasInnoDbTables(dbName))
            {
                //Database has innodb tables. Restore tool does not work on dbs with InnoDb tables.
                MsgBox.Show(this, "InnoDb tables detected. Restore tool cannot run with InnoDb tables.");
                return;
            }
            if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreFromPath.Text, dbName)))           // D:\opendental
            {
                MessageBox.Show(Lan.g(this, "Restore FROM path is invalid.  Unable to find folder named ") + dbName);
                return;
            }
            if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, dbName)))            // C:\mysql\data\opendental
            {
                MessageBox.Show(Lan.g(this, "Restore TO path is invalid.  Unable to find folder named ") + dbName);
                return;
            }
            if (ShouldUseAtoZFolder())
            {
                if (!Directory.Exists(textBackupRestoreAtoZToPath.Text))                 // C:\OpenDentalData\
                {
                    MsgBox.Show(this, "Restore A-Z images TO path is invalid.");
                    return;
                }
                string atozFull = textBackupRestoreAtoZToPath.Text;                                         // C:\OpenDentalData\
                //remove the trailing \
                atozFull = atozFull.Substring(0, atozFull.Length - 1);                                      // C:\OpenDentalData
                string atozDir = atozFull.Substring(atozFull.LastIndexOf(Path.DirectorySeparatorChar) + 1); // OpenDentalData
                if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreFromPath.Text, atozDir)))   // D:\OpenDentalData
                {
                    MsgBox.Show(this, "Restore A-Z images FROM path is invalid.");
                    return;
                }
            }
            string        fromPath = ODFileUtils.CombinePaths(new string[] { textBackupRestoreFromPath.Text, dbName, "" }); // D:\opendental\
            DirectoryInfo dirInfo  = new DirectoryInfo(fromPath);                                                           //does not check to see if dir exists

            if (MessageBox.Show(Lan.g(this, "Restore from backup created on") + "\r\n"
                                + dirInfo.LastWriteTime.ToString("dddd") + "  " + dirInfo.LastWriteTime.ToString()
                                , "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                return;
            }
            Cursor = Cursors.WaitCursor;
            //stop the service--------------------------------------------------------------------------------------
            ServiceController sc = new ServiceController("MySQL");

            if (!ServicesHelper.Stop(sc))
            {
                MsgBox.Show(this, "Unable to stop MySQL service.");
                Cursor = Cursors.Default;
                return;
            }
            //rename the current database---------------------------------------------------------------------------
            //Get a name for the new directory
            string newDb = dbName + "backup_" + DateTime.Today.ToString("MM_dd_yyyy");

            if (Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, newDb)))           //if the new database name already exists
            //find a unique one
            {
                int    uniqueID      = 1;
                string originalNewDb = newDb;
                do
                {
                    newDb = originalNewDb + "_" + uniqueID.ToString();
                    uniqueID++;
                }while(Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, newDb)));
            }
            //move the current db (rename)
            Directory.Move(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, dbName)
                           , ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, newDb));
            //Restore----------------------------------------------------------------------------------------------
            string toPath = textBackupRestoreToPath.Text;          // C:\mysql\data\

            Directory.CreateDirectory(ODFileUtils.CombinePaths(toPath, dirInfo.Name));
            FileInfo[] files = dirInfo.GetFiles();
            curVal = 0;          //curVal gets increased
            for (int i = 0; i < files.Length; i++)
            {
                File.Copy(files[i].FullName, ODFileUtils.CombinePaths(new string[] { toPath, dirInfo.Name, files[i].Name }));
            }
            //start the service--------------------------------------------------------------------------------------
            ServicesHelper.Start(sc);
            Cursor = Cursors.Default;
            //restore A-Z folder, and give user a chance to cancel it.
            if (ShouldUseAtoZFolder())
            {
                FormP        = new FormProgress();
                FormP.MaxVal = 100;              //We will be setting maxVal from worker thread.  (double)fileSize/1024;
                FormP.NumberMultiplication = 100;
                FormP.DisplayText          = ""; //We will set the text from the worker thread.
                FormP.NumberFormat         = "N1";
                //start the thread that will perform the database copy
                Thread workerThread = new Thread(new ThreadStart(InstanceMethodRestore));
                workerThread.Start();
                //display the progress dialog to the user:
                FormP.ShowDialog();
                if (FormP.DialogResult == DialogResult.Cancel)
                {
                    workerThread.Abort();
                    return;
                }
            }
            Version programVersionDb  = new Version(PrefC.GetStringNoCache(PrefName.ProgramVersion));
            Version programVersionCur = new Version(Application.ProductVersion);

            if (programVersionDb != programVersionCur)
            {
                MsgBox.Show(this, "The restored database version is different than the version installed and requires a restart.  The program will now close.");
                FormOpenDental.S_ProcessKillCommand();
                return;
            }
            else
            {
                DataValid.SetInvalid(Cache.GetAllCachedInvalidTypes().ToArray());
            }
            MsgBox.Show(this, "Done");
            Close();
            return;
        }
Example #7
0
        ///<summary>This is the function that the worker thread uses to perform the backup.</summary>
        private void InstanceMethodBackup()
        {
            curVal = 0;
            Invoke(new PassProgressDelegate(PassProgressToDialog), new object [] { curVal,
                                                                                   Lan.g(this, "Preparing to copy database"), //this happens very fast and probably won't be noticed.
                                                                                   100, "" });                                //max of 100 keeps dlg from closing
            string dbName         = MiscData.GetCurrentDatabase();
            ulong  driveFreeSpace = 0;
            double dbSize         = GetFileSizes(textBackupFromPath.Text + dbName) / 1024;

            //Attempt to get the free disk space on the drive or share of the destination folder.
            //If the free space cannot be determined the backup will be attempted anyway (old behavior).
            if (ODFileUtils.GetDiskFreeSpace(textBackupToPath.Text, out driveFreeSpace))
            {
                if ((ulong)dbSize * 1024 * 1024 >= driveFreeSpace)           //dbSize is in megabytes, cast to ulong to compare. It will never be negative so this is safe.
                {
                    Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Not enough free disk space available on the destination drive to backup the database.") });
                    //We now want to automatically close FormProgress.  This is done by clearing out the variables.
                    Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" });
                    return;
                }
            }
            try{
                string dbtopath = ODFileUtils.CombinePaths(textBackupToPath.Text, dbName);
                if (Directory.Exists(dbtopath))                // D:\opendental
                {
                    int loopCount = 1;
                    while (Directory.Exists(dbtopath + "backup_" + loopCount))
                    {
                        loopCount++;
                    }
                    Directory.Move(dbtopath, dbtopath + "backup_" + loopCount);
                }
                string        fromPath = ODFileUtils.CombinePaths(textBackupFromPath.Text, dbName);
                string        toPath   = textBackupToPath.Text;
                DirectoryInfo dirInfo  = new DirectoryInfo(fromPath);             //does not check to see if dir exists
                Directory.CreateDirectory(ODFileUtils.CombinePaths(toPath, dirInfo.Name));
                FileInfo[] files = dirInfo.GetFiles();
                curVal = 0;              //curVal gets increased
                for (int i = 0; i < files.Length; i++)
                {
                    string fromFile = files[i].FullName;
                    string toFile   = ODFileUtils.CombinePaths(new string[] { toPath, dirInfo.Name, files[i].Name });
                    if (File.Exists(toFile))
                    {
                        if (files[i].LastWriteTime != File.GetLastWriteTime(toFile))                       //if modification dates don't match
                        {
                            FileAttributes fa         = File.GetAttributes(toFile);
                            bool           isReadOnly = ((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);
                            if (isReadOnly)
                            {
                                //If the destination file exists and is marked as read only, then we must mark it as a
                                //normal read/write file before it may be overwritten.
                                File.SetAttributes(toFile, FileAttributes.Normal);                               //Remove read only from the destination file.
                            }
                            File.Copy(fromFile, toFile, true);
                        }
                    }
                    else                        //file doesn't exist, so just copy
                    {
                        File.Copy(fromFile, toFile);
                    }
                    curVal += (double)files[i].Length / (double)1024 / (double)1024;
                    if (curVal < dbSize)                  //this avoids setting progress bar to max, which would close the dialog.
                    {
                        Invoke(new PassProgressDelegate(PassProgressToDialog), new object [] { curVal,
                                                                                               Lan.g(this, "Database: ?currentVal MB of ?maxVal MB copied"),
                                                                                               dbSize, "" });
                    }
                }
            }
            catch {           //for instance, if abort.
                //If the user aborted, FormP will return DialogResult.Cancel which will not cause this error text to be displayed to the user.  See butBackup_Click for more info.
                Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Backup failed.") });
                //We now want to automatically close FormProgress.  This is done by clearing out the variables.
                Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" });
                return;
            }
            //A to Z folder------------------------------------------------------------------------------------
            try {
                if (ShouldUseAtoZFolder())
                {
                    string atozFull = ODFileUtils.RemoveTrailingSeparators(ImageStore.GetPreferredAtoZpath());
                    string atozDir  = atozFull.Substring(atozFull.LastIndexOf(Path.DirectorySeparatorChar) + 1);               //OpenDentalData
                    Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0,
                                                                                          Lan.g(this, "Calculating size of files in A to Z folder."),
                                                                                          100, "" });//max of 100 keeps dlg from closing
                    long atozSize = GetFileSizes(ODFileUtils.CombinePaths(atozFull, ""),
                                                 ODFileUtils.CombinePaths(new string[] { textBackupToPath.Text, atozDir, "" })) / 1024;
                    driveFreeSpace = 0;
                    //Attempt to get the free disk space on the drive or share of the destination folder.
                    //If the free space cannot be determined the backup will be attempted anyway (old behavior).
                    if (ODFileUtils.GetDiskFreeSpace(textBackupToPath.Text, out driveFreeSpace))
                    {
                        if ((ulong)(atozSize * 1024 * 1024) >= driveFreeSpace)                   //atozSize is in megabytes, cast to ulong in order to compare.  It will never be negative so it's safe.
                        //Not enough free space to perform the backup.
                        {
                            throw new ApplicationException(Lan.g(this, "Backing up A to Z images folder failed.  Not enough free disk space available on the destination drive.")
                                                           + "\r\n" + Lan.g(this, "AtoZ folder size:") + " " + atozSize * 1024 * 1024 + "B\r\n"
                                                           + Lan.g(this, "Destination available space:") + " " + driveFreeSpace + "B");
                        }
                    }
                    if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupToPath.Text, atozDir)))                    // D:\OpenDentalData
                    {
                        Directory.CreateDirectory(ODFileUtils.CombinePaths(textBackupToPath.Text, atozDir));            // D:\OpenDentalData
                    }
                    curVal = 0;
                    CopyDirectoryIncremental(ODFileUtils.CombinePaths(atozFull, ""),                                        // C:\OpenDentalData\
                                             ODFileUtils.CombinePaths(new string[] { textBackupToPath.Text, atozDir, "" }), // D:\OpenDentalData\
                                             atozSize);
                }
            }
            catch (ApplicationException ex) {
                Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { ex.Message });
            }
            catch {
                Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Backing up A to Z images folder failed.  User might not have enough permissions or a file might be in use.") });
            }
            //force dialog to close even if no files copied or calculation was slightly off.
            Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" });
        }
Example #8
0
        private void butBackup_Click(object sender, System.EventArgs e)
        {
            if (!IsBackupTabValid())
            {
                return;
            }
            //Ensure that the backup from and backup to paths are different. This is to prevent the live database
            //from becoming corrupt.
            if (this.textBackupFromPath.Text.Trim().ToLower() == this.textBackupToPath.Text.Trim().ToLower())
            {
                MsgBox.Show(this, "The backup from path and backup to path must be different.");
                return;
            }
            //test saving defaults
            if (textBackupFromPath.Text != PrefC.GetString(PrefName.BackupFromPath) ||
                textBackupToPath.Text != PrefC.GetString(PrefName.BackupToPath) ||
                textBackupRestoreFromPath.Text != PrefC.GetString(PrefName.BackupRestoreFromPath) ||
                textBackupRestoreToPath.Text != PrefC.GetString(PrefName.BackupRestoreToPath) ||
                textBackupRestoreAtoZToPath.Text != PrefC.GetString(PrefName.BackupRestoreAtoZToPath))
            {
                if (MsgBox.Show(this, MsgBoxButtons.YesNo, "Set as default?") && SaveTabPrefs())
                {
                    DataValid.SetInvalid(InvalidType.Prefs);
                }
            }
            string dbName = MiscData.GetCurrentDatabase();

            if (InnoDb.HasInnoDbTables(dbName))
            {
                //Database has innodb tables. Backup tool does not work on dbs with InnoDb tables.
                MsgBox.Show(this, "InnoDb tables detected. Backup tool cannot run with InnoDb tables.");
                return;
            }
            if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupFromPath.Text, dbName)))           // C:\mysql\data\opendental
            {
                MsgBox.Show(this, "Backup FROM path is invalid.");
                return;
            }
            if (!Directory.Exists(textBackupToPath.Text))            // D:\
            {
                MsgBox.Show(this, "Backup TO path is invalid.");
                return;
            }
            _errorMessage = "";
            FormP         = new FormProgress();
            FormP.MaxVal  = 100;             //We will be setting maxVal from worker thread.  (double)fileSize/1024;
            FormP.NumberMultiplication = 100;
            FormP.DisplayText          = ""; //We will set the text from the worker thread.
            FormP.NumberFormat         = "N1";
            //start the thread that will perform the database copy
            Thread workerThread = new Thread(new ThreadStart(InstanceMethodBackup));

            workerThread.Start();
            //display the progress dialog to the user:
            FormP.ShowDialog();
            if (FormP.DialogResult == DialogResult.Cancel)
            {
                workerThread.Abort();
                return;
            }
            if (_errorMessage == "")
            {
                SecurityLogs.MakeLogEntry(Permissions.Backup, 0, Lan.g(this, "Database backup created at ") + textBackupToPath.Text);
                MessageBox.Show(Lan.g(this, "Backup complete."));
            }
            else              //Backup failed for some reason.
            {
                MessageBox.Show(_errorMessage);
            }
            Close();
        }