예제 #1
0
        /// <summary>
        /// see if any patches are missing; is there a direct line between FCurrentlyInstalledVersion and FLatestAvailablePatch?
        /// </summary>
        /// <returns>return a list of all patches that should be applied. empty list if there is a problem</returns>
        public SortedList CheckPatchesConsistent(SortedList AOrderedListOfAllPatches)
        {
            SortedList ResultPatchList = new SortedList();
            TFileVersionInfo testPatchVersion;

            // get the latest patch that is available
            FLatestAvailablePatch = new TFileVersionInfo(FCurrentlyInstalledVersion);

            foreach (string patch in AOrderedListOfAllPatches.GetValueList())
            {
                testPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(patch);

                if (testPatchVersion.Compare(FLatestAvailablePatch) > 0)
                {
                    FLatestAvailablePatch = testPatchVersion;
                }
            }

            // drop unnecessary patch files
            // ie. patch files leading to the same version, eg. 2.2.11-1 and 2.2.12-2 to 2.2.12-3
            // we only want the biggest step
            testPatchVersion = new TFileVersionInfo(FCurrentlyInstalledVersion);
            bool patchesAvailable = true;

            while (patchesAvailable)
            {
                StringCollection applyingPatches = new StringCollection();

                foreach (string patch in AOrderedListOfAllPatches.GetValueList())
                {
                    if (TPatchFileVersionInfo.PatchApplies(testPatchVersion, patch))
                    {
                        applyingPatches.Add(patch);
                    }
                }

                patchesAvailable = (applyingPatches.Count > 0);

                if (applyingPatches.Count > 0)
                {
                    // see which of the applying patches takes us further
                    string highestPatch = applyingPatches[0];
                    TFileVersionInfo highestPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(highestPatch);

                    foreach (string patch in applyingPatches)
                    {
                        if (TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(patch).Compare(highestPatchVersion) > 0)
                        {
                            highestPatch = patch;
                            highestPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(highestPatch);
                        }
                    }

                    ResultPatchList.Add(highestPatch, highestPatch);
                    testPatchVersion = highestPatchVersion;
                }
            }

            if (FLatestAvailablePatch.Compare(testPatchVersion) != 0)
            {
                // check for a generic patch file, starting from version 0.0.99.99
                foreach (string patch in AOrderedListOfAllPatches.GetValueList())
                {
                    if (patch.Contains("0.0.99.99"))
                    {
                        testPatchVersion = TPatchFileVersionInfo.GetLatestPatchVersionFromDiffZipName(patch);
                        ResultPatchList.Clear();
                        ResultPatchList.Add(patch, patch);
                    }
                }
            }

            if (FLatestAvailablePatch.Compare(testPatchVersion) != 0)
            {
                TLogging.Log("missing patchfile from version " + testPatchVersion.ToString() + " to " + FLatestAvailablePatch.ToString());
                return new SortedList();
            }

            return ResultPatchList;
        }
예제 #2
0
        /// <summary>
        /// apply one single database patch.
        /// if this is the last patch, an email could be sent, etc
        /// </summary>
        /// <param name="ADesiredVersion"></param>
        /// <param name="ALastPatch"></param>
        /// <returns></returns>
        private Boolean RunDBPatch(TFileVersionInfo ADesiredVersion, Boolean ALastPatch)
        {
            TDBTransaction WriteTransaction = null;
            bool SubmissionResult = false;

            // TODO: run sql script or code from DLL to update the database
            // TODO: if last patch, send an email to central support etc
            TLogging.Log("RunDBPatch " + ADesiredVersion.ToString());


            // find appropriate sql script that updates to this version
            string[] files = Directory.GetFiles(FPatchesPath,
                String.Format("*_{0}.{1}.{2}.sql",
                    ADesiredVersion.FileMajorPart,
                    ADesiredVersion.FileMinorPart,
                    ADesiredVersion.FileBuildPart));

            if (files.Length > 1)
            {
                throw new Exception("There are too many files for upgrading to version " + ADesiredVersion.ToString() + " in " + FPatchesPath);
            }

            if (files.Length == 0)
            {
                throw new Exception("We cannot find a file for upgrading to version " + ADesiredVersion.ToString() + " in " + FPatchesPath);
            }

            TLogging.Log("Applying " + Path.GetFileName(files[0]));

            DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref WriteTransaction,
                ref SubmissionResult,
                delegate
                {
                    // always upgrade the version number
                    DBAccess.GDBAccessObj.ExecuteNonQuery(
                        String.Format(
                            "UPDATE s_system_defaults SET s_default_value_c = '{0}.{1}.{2}-0' WHERE s_default_code_c='CurrentDatabaseVersion'",
                            ADesiredVersion.FileMajorPart,
                            ADesiredVersion.FileMinorPart,
                            ADesiredVersion.FileBuildPart), WriteTransaction);

                    StreamReader reader = new StreamReader(files[0]);
                    string line;
                    string stmt = string.Empty;

                    while ((line = reader.ReadLine()) != null)
                    {
                        if (!line.Trim().StartsWith("--"))
                        {
                            if (!line.Trim().EndsWith(";"))
                            {
                                stmt += line.Trim() + " ";
                            }
                            else
                            {
                                stmt += line.Trim();
                                DBAccess.GDBAccessObj.ExecuteNonQuery(stmt, WriteTransaction);
                            }
                        }

                        if (stmt.Length > 0)
                        {
                            DBAccess.GDBAccessObj.ExecuteNonQuery(stmt, WriteTransaction);
                        }
                    }

                    SubmissionResult = true;
                });

            return true;
        }
예제 #3
0
        /// <summary>
        /// Import all data of a partner from a text file, using a format used by Petra 2.x.
        /// Containing: partner, person/family/church/etc record, valid locations, contact details, special types,
        ///             interests, personnel data, commitments, applications, etc.
        /// For UNITs there is more specific data, used eg. for the events file.
        /// </summary>
        /// <param name="ALinesToImport"></param>
        /// <param name="ALimitToOption">if this is not an empty string, only the applications for this conference will be imported, historic applications will be ignored</param>
        /// <param name="ADoNotOverwrite">do not modify records that already exist in the database</param>
        /// <param name="AResultList">verification results. can contain critical errors and messages for the user</param>
        /// <returns>nothing - an empty TDS</returns>
        public PartnerImportExportTDS ImportAllData(string[] ALinesToImport,
            string ALimitToOption,
            bool ADoNotOverwrite,
            out TVerificationResultCollection AResultList)
        {
            FResultList = new TVerificationResultCollection();
            FCountLocationKeys = -1;
            FLimitToOption = ALimitToOption;
            FDoNotOverwrite = ADoNotOverwrite;
            FMainDS = new PartnerImportExportTDS();

            InitReading(ALinesToImport);

            TFileVersionInfo PetraVersion = new TFileVersionInfo(ReadString());
            ReadInt64(); // SiteKey
            ReadInt32(); // SubVersion

            if ((PetraVersion.FileMajorPart < 3) && (PetraVersion.FileMinorPart < 2))
            {
                AddVerificationResult(
                    "EXT import not supported from old file type: " + PetraVersion.ToString(), TResultSeverity.Resv_Critical);
            }
            else
            {
                TDBTransaction Transaction = null;
                bool SubmissionOK = false;

                DBAccess.GDBAccessObj.GetNewOrExistingAutoTransaction(IsolationLevel.Serializable,
                    ref Transaction,
                    ref SubmissionOK,
                    delegate
                    {
                        try
                        {
                            while (CheckForKeyword("PARTNER"))
                            {
                                PPartnerRow PartnerRow = ImportPartner(Transaction);

                                ImportPartnerClassSpecific(PartnerRow.PartnerClass, PetraVersion, Transaction);

                                ImportLocation(Transaction);

                                ImportOptionalDetails(PartnerRow, PetraVersion, Transaction);
                            }

                            ImportContext = "Checking data references";

                            CheckRequiredUnits(Transaction);
                            //                AddRequiredUnits(FRequiredOfficeKeys, "F", 1000000, "Office", Transaction);
                            //                AddRequiredUnits(FRequiredOptionKeys, "CONF", 1000000, "Conference", Transaction);

                            if (FParsingOfPartnerLocationsForContactDetailsNecessary)
                            {
                                TPartnerContactDetails_LocationConversionHelper.PartnerAttributeLoadUsingTemplate =
                                    PPartnerAttributeAccess.LoadUsingTemplate;
                                TPartnerContactDetails_LocationConversionHelper.SequenceGetter =
                                    MCommon.WebConnectors.TSequenceWebConnector.GetNextSequence;

                                TPartnerContactDetails_LocationConversionHelper.ParsePartnerLocationsForContactDetails(FMainDS,
                                    Transaction);
                            }
                        }
                        catch (Exception e)
                        {
                            TLogging.Log(e.GetType().ToString() + ": " + e.Message + " in line " + (CurrentLineCounter + 1).ToString());
                            TLogging.Log(CurrentLine);
                            TLogging.Log(e.StackTrace);
                            throw;
                        }

                        SubmissionOK = true;
                    });
            }

            AResultList = FResultList;

            if (!TVerificationHelper.IsNullOrOnlyNonCritical(AResultList))
            {
                return new PartnerImportExportTDS();
            }

            return FMainDS;
        }
예제 #4
0
        public static bool ResetDatabase(string AZippedNewDatabaseData)
        {
            List <string>tables = TTableList.GetDBNames();

            TProgressTracker.InitProgressTracker(DomainManager.GClientID.ToString(),
                Catalog.GetString("Importing database"),
                tables.Count + 3);

            TDBTransaction Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);

            try
            {
                tables.Reverse();

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("deleting current data"),
                    0);

                foreach (string table in tables)
                {
                    DBAccess.GDBAccessObj.ExecuteNonQuery("DELETE FROM pub_" + table, Transaction);
                }

                if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == true)
                {
                    TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                TSimpleYmlParser ymlParser = new TSimpleYmlParser(PackTools.UnzipString(AZippedNewDatabaseData));

                ymlParser.ParseCaptions();

                tables.Reverse();

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("loading initial tables"),
                    1);

                // one transaction to import the user table and user permissions. otherwise logging in will not be possible if other import fails?
                bool success = true;
                success = success && LoadTable("s_user", ymlParser, Transaction);
                success = success && LoadTable("s_module", ymlParser, Transaction);
                success = success && LoadTable("s_user_module_access_permission", ymlParser, Transaction);
                success = success && LoadTable("s_system_defaults", ymlParser, Transaction);
                success = success && LoadTable("s_system_status", ymlParser, Transaction);

                // make sure we have the correct database version
                TFileVersionInfo serverExeInfo = new TFileVersionInfo(TSrvSetting.ApplicationVersion);
                DBAccess.GDBAccessObj.ExecuteNonQuery(String.Format(
                        "UPDATE PUB_s_system_defaults SET s_default_value_c = '{0}' WHERE s_default_code_c = 'CurrentDatabaseVersion'",
                        serverExeInfo.ToString()), Transaction);

                if (!success)
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == true)
                {
                    TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
                    DBAccess.GDBAccessObj.RollbackTransaction();
                    return false;
                }

                DBAccess.GDBAccessObj.CommitTransaction();

                tables.Remove("s_user");
                tables.Remove("s_module");
                tables.Remove("s_user_module_access_permission");
                tables.Remove("s_system_defaults");
                tables.Remove("s_system_status");

                FCurrencyPerLedger = new SortedList <int, string>();

                Transaction = DBAccess.GDBAccessObj.BeginTransaction(IsolationLevel.Serializable);

                int tableCounter = 2;

                foreach (string table in tables)
                {
                    TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                        String.Format(Catalog.GetString("loading table {0}"), table),
                        tableCounter);

                    tableCounter++;

                    if (TProgressTracker.GetCurrentState(DomainManager.GClientID.ToString()).CancelJob == true)
                    {
                        TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
                        DBAccess.GDBAccessObj.RollbackTransaction();
                        return false;
                    }

                    LoadTable(table, ymlParser, Transaction);
                }

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("loading sequences"),
                    tables.Count + 5 + 3);

                // set sequences appropriately, not lagging behind the imported data
                foreach (string seq in TTableList.GetDBSequenceNames())
                {
                    LoadSequence(seq, ymlParser, Transaction);
                }

                TProgressTracker.SetCurrentState(DomainManager.GClientID.ToString(),
                    Catalog.GetString("finish import"),
                    tables.Count + 5 + 4);

                DBAccess.GDBAccessObj.CommitTransaction();

                // reset all cached tables
                TCacheableTablesManager.GCacheableTablesManager.MarkAllCachedTableNeedsRefreshing();

                TProgressTracker.FinishJob(DomainManager.GClientID.ToString());
            }
            catch (Exception e)
            {
                TLogging.Log("Problem in ResetDatabase: " + e.Message);
                TLogging.Log(e.StackTrace);
                DBAccess.GDBAccessObj.RollbackTransaction();
                return false;
            }

            return true;
        }
예제 #5
0
        public static bool ResetDatabase(string AZippedNewDatabaseData)
        {
            List <string>tables = TTableList.GetDBNames();
            bool SubmissionResult = false;
            TDBTransaction Transaction = null;

            string ClientID = "ClientID";

            try
            {
                ClientID = DomainManager.GClientID.ToString();
            }
            catch (Exception)
            {
            }

            TProgressTracker.InitProgressTracker(ClientID,
                Catalog.GetString("Restoring Database..."),
                tables.Count + 3);

            DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref Transaction,
                ref SubmissionResult,
                delegate
                {
                    try
                    {
                        tables.Reverse();

                        TProgressTracker.SetCurrentState(ClientID,
                            Catalog.GetString("Deleting current data..."),
                            0);

                        foreach (string table in tables)
                        {
                            DBAccess.GDBAccessObj.ExecuteNonQuery("DELETE FROM pub_" + table, Transaction);
                        }

                        if (TProgressTracker.GetCurrentState(ClientID).CancelJob == true)
                        {
                            TProgressTracker.FinishJob(ClientID);

                            // As SubmissionResult is still false, a DB Transaction Rollback will get
                            // executed automatically and the Method will be exited with return value 'false'!
                            return;
                        }

                        TSimpleYmlParser ymlParser = new TSimpleYmlParser(PackTools.UnzipString(AZippedNewDatabaseData));

                        ymlParser.ParseCaptions();

                        tables.Reverse();

                        TProgressTracker.SetCurrentState(ClientID,
                            Catalog.GetString("Loading initial tables..."),
                            1);

                        // one transaction to import the user table and user permissions. otherwise logging in will not be possible if other import fails?
                        bool success = true;
                        success = success && LoadTable("s_user", ymlParser, Transaction);
                        success = success && LoadTable("s_module", ymlParser, Transaction);
                        success = success && LoadTable("s_user_module_access_permission", ymlParser, Transaction);
                        success = success && LoadTable("s_system_defaults", ymlParser, Transaction);
                        success = success && LoadTable("s_system_status", ymlParser, Transaction);

                        // make sure we have the correct database version
                        TFileVersionInfo serverExeInfo = new TFileVersionInfo(TSrvSetting.ApplicationVersion);
                        DBAccess.GDBAccessObj.ExecuteNonQuery(String.Format(
                                "UPDATE PUB_s_system_defaults SET s_default_value_c = '{0}' WHERE s_default_code_c = 'CurrentDatabaseVersion'",
                                serverExeInfo.ToString()), Transaction);

                        if (!success)
                        {
                            // As SubmissionResult is still TSubmitChangesResult.scrError, a DB Transaction Rollback will get
                            // executed automatically and the Method will be exited with return value 'false'!
                            return;
                        }

                        if (TProgressTracker.GetCurrentState(ClientID).CancelJob == true)
                        {
                            TProgressTracker.FinishJob(ClientID);

                            // As SubmissionResult is still false, a DB Transaction Rollback will get
                            // executed automatically and the Method will be exited with return value 'false'!
                            return;
                        }

                        tables.Remove("s_user");
                        tables.Remove("s_module");
                        tables.Remove("s_user_module_access_permission");
                        tables.Remove("s_system_defaults");
                        tables.Remove("s_system_status");

                        FCurrencyPerLedger = new SortedList <int, string>();

                        int tableCounter = 2;

                        foreach (string table in tables)
                        {
                            TProgressTracker.SetCurrentState(ClientID,
                                String.Format(Catalog.GetString("Loading Table {0}..."), table),
                                tableCounter);

                            tableCounter++;

                            if (TProgressTracker.GetCurrentState(ClientID).CancelJob == true)
                            {
                                TProgressTracker.FinishJob(ClientID);

                                // As SubmissionResult is still false, a DB Transaction Rollback will get
                                // executed automatically and the Method will be exited with return value 'false'!
                                return;
                            }

                            LoadTable(table, ymlParser, Transaction);
                        }

                        TProgressTracker.SetCurrentState(ClientID,
                            Catalog.GetString("Loading Sequences..."),
                            tables.Count + 5 + 3);

                        // set sequences appropriately, not lagging behind the imported data
                        foreach (string seq in TTableList.GetDBSequenceNames())
                        {
                            LoadSequence(seq, ymlParser, Transaction);
                        }

                        TProgressTracker.SetCurrentState(ClientID,
                            Catalog.GetString("Finishing Restore..."),
                            tables.Count + 5 + 4);

                        SubmissionResult = true;

                        // reset all cached tables
                        TCacheableTablesManager.GCacheableTablesManager.MarkAllCachedTableNeedsRefreshing();

                        TProgressTracker.FinishJob(ClientID);
                    }
                    catch (Exception e)
                    {
                        TLogging.Log("Problem in ResetDatabase: " + e.ToString());
                        TLogging.LogStackTrace(TLoggingType.ToLogfile);

                        throw;
                    }
                });

            return SubmissionResult;
        }
예제 #6
0
        /// <summary>
        /// Import all data of a partner from a text file, using a format used by Petra 2.x.
        /// containing: partner, person/family/church/etc record, valid locations, special types,
        ///             interests, personnel data, commitments, applications
        /// for units there is more specific data, used eg. for the events file
        /// </summary>
        /// <param name="ALinesToImport"></param>
        /// <param name="ALimitToOption">if this is not an empty string, only the applications for this conference will be imported, historic applications will be ignored</param>
        /// <param name="ADoNotOverwrite">do not modify records that already exist in the database</param>
        /// <param name="AResultList">verification results. can contain critical errors and messages for the user</param>
        /// <returns>nothing - an empty TDS</returns>
        public PartnerImportExportTDS ImportAllData(string[] ALinesToImport,
            string ALimitToOption,
            bool ADoNotOverwrite,
            out TVerificationResultCollection AResultList)
        {
            FResultList = new TVerificationResultCollection();
            FCountLocationKeys = -1;
            FLimitToOption = ALimitToOption;
            FDoNotOverwrite = ADoNotOverwrite;
            FMainDS = new PartnerImportExportTDS();
            TDBTransaction Transaction;
            Boolean NewTransaction;

            InitReading(ALinesToImport);

            TFileVersionInfo PetraVersion = new TFileVersionInfo(ReadString());
            ReadInt64(); // SiteKey
            ReadInt32(); // SubVersion

            if ((PetraVersion.FileMajorPart < 3) && (PetraVersion.FileMinorPart < 2))
            {
                AddVerificationResult(
                    "EXT import not supported from old file type: " + PetraVersion.ToString(), TResultSeverity.Resv_Critical);
            }
            else
            {
                try
                {
                    Transaction = DBAccess.GDBAccessObj.GetNewOrExistingTransaction(IsolationLevel.Serializable, out NewTransaction);

                    while (CheckForKeyword("PARTNER"))
                    {
                        PPartnerRow PartnerRow = ImportPartner(Transaction);

                        ImportPartnerClassSpecific(PartnerRow.PartnerClass, PetraVersion, Transaction);

                        ImportLocation(Transaction);

                        ImportOptionalDetails(PartnerRow, PetraVersion, Transaction);
                    }

                    ImportContext = "Checking data references";

                    CheckRequiredUnits(Transaction);
                    //                AddRequiredUnits(FRequiredOfficeKeys, "F", 1000000, "Office", Transaction);
                    //                AddRequiredUnits(FRequiredOptionKeys, "CONF", 1000000, "Conference", Transaction);
                }
                catch (Exception e)
                {
                    TLogging.Log(e.GetType().ToString() + ": " + e.Message + " in line " + (CurrentLineCounter + 1).ToString());
                    TLogging.Log(CurrentLine);
                    TLogging.Log(e.StackTrace);
                    throw;
                }
                finally
                {
                    DBAccess.GDBAccessObj.RollbackTransaction();
                }
            }

            AResultList = FResultList;

            if (!TVerificationHelper.IsNullOrOnlyNonCritical(AResultList))
            {
                return new PartnerImportExportTDS();
            }

            return FMainDS;
        }
예제 #7
0
        /// <summary>
        /// runs all patches against the database;
        /// can send an email when the last patch has been applied (see RunDBPatch)
        /// </summary>
        public Boolean RunDBPatches()
        {
            Boolean ReturnValue = false;
            TFileVersionInfo dbVersion;
            TFileVersionInfo appVersion;
            TFileVersionInfo desiredVersion;
            Boolean lastPatch;

            DBAccess.GDBAccessObj = new TDataBase();
            DBAccess.GDBAccessObj.EstablishDBConnection(CommonTypes.ParseDBType(TAppSettingsManager.GetValue("Server.RDBMSType")),
                TAppSettingsManager.GetValue("Server.DBHostOrFile"),
                TAppSettingsManager.GetValue("Server.DBPort"),
                TAppSettingsManager.GetValue("Server.DBName"),
                TAppSettingsManager.GetValue("Server.DBUserName"),
                TAppSettingsManager.GetValue("Server.DBPassword"),
                "");

            dbVersion = GetDBPatchLevel();
            dbVersion.FilePrivatePart = 0;
            TLogging.Log("Current version of the database is " + dbVersion.ToString());

            if (dbVersion != null)
            {
                ReturnValue = true;

                StreamReader sr = new StreamReader(FPatchesPath + Path.DirectorySeparatorChar + "version.txt");
                appVersion = new TFileVersionInfo(sr.ReadLine());
                appVersion.FilePrivatePart = 0;
                TLogging.Log("We want to update to version " + appVersion.ToString());
                sr.Close();

                if (dbVersion.Compare(appVersion) == 0)
                {
                    // rerun the last patch; perhaps the patch file itself was patched
                    ReturnValue = RunDBPatch(dbVersion, true);
                }

                for (Int32 Counter = dbVersion.FileBuildPart + 1; Counter <= appVersion.FileBuildPart; Counter += 1)
                {
                    if (ReturnValue)
                    {
                        desiredVersion = new TFileVersionInfo(dbVersion);
                        desiredVersion.FileBuildPart = (ushort)Counter;
                        lastPatch = (Counter == appVersion.FileBuildPart);
                        ReturnValue = RunDBPatch(desiredVersion, lastPatch);
                    }
                }
            }

            return ReturnValue;
        }