///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Archives database.
        /// This method creates archive database if the original one contains
        /// data to archive and cleans original database (removes archived data).
        /// If method succeeds, archive will contain schedules older than
        /// specified date.
        /// If original database does not contain data to archive, archive file
        /// will not be created and DbArchiveResult.IsArchiveCreated property
        /// will be set to "false".
        /// Method throws an exception if failure occures.
        /// </summary>
        /// <param name="path">
        /// File path of original database.
        /// </param>
        /// <param name="date">
        /// Schedules older than this date will be archived.
        /// </param>
        /// <returns>
        /// DbArchiveResult object.
        /// </returns>
        public static DbArchiveResult ArchiveDatabase(string path, DateTime date)
        {
            Debug.Assert(path != null);

            bool     isCreated = false;
            DateTime?firstDate = null;
            DateTime?lastDate  = null;

            string baseConnStr = DatabaseHelper.BuildSqlConnString(path, true);
            string archPath    = null;

            // check if database has schedules to archive
            if (_HasDataToArchive(baseConnStr, date))
            {
                // make archive file path
                archPath = _BuildArchivePath(path);

                // copy original file
                File.Copy(path, archPath);

                try
                {
                    string archConnStr = DatabaseHelper.BuildSqlConnString(
                        archPath,
                        true);

                    // apply script to archive
                    _ApplyScript(archConnStr, ResourceLoader.ReadFileAsString(ARCHIVE_SCRIPT_FILE_NAME),
                                 date);

                    // query archive dates
                    _QueryDates(archConnStr, out firstDate, out lastDate);

                    // compact archive file
                    SqlCeEngine engine = new SqlCeEngine(archConnStr);
                    engine.Shrink();

                    // apply script to original database
                    _ApplyScript(baseConnStr, ResourceLoader.ReadFileAsString(CLEAN_SCRIPT_FILE_NAME),
                                 date);

                    isCreated = true;
                }
                catch
                {
                    DatabaseEngine.DeleteDatabase(archPath);
                    throw;
                }
            }

            return(new DbArchiveResult(archPath, isCreated, firstDate, lastDate));
        }
        /// <summary>
        /// Method calls database engine for execution upgade scripts.
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="projectVer"></param>
        private static void _UpgradeDB(string connectionString, double projectVersion)
        {
            Debug.Assert(!string.IsNullOrEmpty(connectionString));
            Debug.Assert(SchemeVersion.StartVersion <= projectVersion);

            foreach (var upgradeScript in SchemeVersion.GetUpgradeScripts(projectVersion))
            {
                if (upgradeScript == null)
                {
                    throw new DataException(Properties.Messages.Error_GetUpgradeScriptFailed);
                }

                DatabaseEngine.ExecuteScript(connectionString, upgradeScript, null);
            }
        }
        ///////////////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////////////

        private static void _ApplyScript(string connStr, string script,
                                         DateTime date)
        {
            Debug.Assert(connStr != null);
            Debug.Assert(script != null);

            // upgrade database if necessary
            DatabaseOpener.CheckForDbUpgrade(connStr);

            // script parameters
            SqlCeParameter[] paramArray = new SqlCeParameter[]
            {
                new SqlCeParameter("@date", date)
            };

            // apply script
            DatabaseEngine.ExecuteScript(connStr, script, paramArray);
        }