<%@language = "javascript" %>
<% /*
    $Revision$
    $Id$

    File:           dbupgrade.asp
    Description:    Zoek in folder appl/upg/ een DB36.sql en voer deze uit
    Note:           We passen daarbij op dat per database maximaal één gebruiker tegelijk de upgrade uitvoert
                    Pas in het bijzonder op voor (KFPP, VENR) waar twee customerId naar dezelfde database
                    wijzen. Daarom registreren we de actieve upgrade in de database in 'fac_version_upgrading'


    TODO: Super robuustheid als een SQL faalt fac_version_upgrading resetten?
    TODO: Als we detecteren dan een andere gebruiker met de upgrade bezig is,
          kunnen/moeten we daar op wachten of op hoop van zegen doorgaan?
*/
DOCTYPE_Disable = 1;
ANONYMOUS_Allowed = 1;
EXPIRED_PASSWORD_OK = 1;
LOGIN_try = 1; // prevent recursion
DBUPGRADE = 1; // prevent recursion
NO_ADDHEADER = 1; // common.inc voert wat globale acties hierdoor niet meer uit
%>
<!-- #include file="../Shared/common.inc" -->
<%
    myLog("Entering DBUPGRADE.asp");

    var mustContinue = true;
    function myLog(s, optionalColor)
    {
        __DoLog("Session {0}: {1}".format(Session.SessionID, s), optionalColor);
    }

    var fso = Server.CreateObject("Scripting.FileSystemObject");

    myLog("Force settings reload");
    settings.loadSET(true); // Forceer caching opnieuw, doet zelf ook Application.Lock()/Unlock

    var db_schema = Application("SET_" + customerId + "_DB_SCHEMA");
    var upgrade_script = Server.MapPath(rooturl) + '/appl/upg/DB{0}.sql'.format(db_schema);
    if (!fso.FileExists(upgrade_script))
    {   // Ondertussen is de upgrade waarschijnlijk al voltooid door een andere gebruiker
        myLog("Exit DBUPGRADE.asp\nUpgrade already done by another session?");
        mustContinue = false;
    }

    if (mustContinue)
    {
        // Probeer te voorkomen dat twee gebruikers tegelijk dezelfde database
        // gaan bijwerken. Gebruik fac_version_upgrading als semafoor
        var sql = "UPDATE fac_version"
                + "   SET fac_version_upgrading = " + safe.quoted_sql(Session.SessionID)
                + " WHERE fac_version_upgrading IS NULL"; //  De IS NULL maakt het multi-user safe
        Oracle.Execute(sql);
        // Is het gelukt?
        var sql = "SELECT fac_version_upgrading"
                + "  FROM fac_version";
        var oRs = Oracle.Execute(sql);
        var upgrading = oRs("fac_version_upgrading").Value;
        oRs.Close();
        if (upgrading != Session.SessionID)
        {   // Ondertussen is een andere gebruiker waarschijnlijk al begonnen met de upgrade
            myLog("Exit DBUPGRADE.asp\nSkipping because upgrade is in progress by session {0}".format(upgrading));
            // TODO: Wachten in een loopje tot die andere klaar is?
            mustContinue = false;
        }
    }

    if (mustContinue) // *Wij* gaan de echte upgrade uitvoeren
    {
        myLog("Schema version was {0}".format(db_schema));
        myLog("Starting upgrade {0}".format(upgrade_script));

        // Doe de echte upgrade. Op dit moment zijn wij de enige gebruiker van customerId die 'draait'
        var ftekst = fso.OpenTextFile(upgrade_script);
        var sqltekst = ftekst.ReadAll();
        ftekst.Close();

// Simuleer trage upgrade voor multi-user testing
// var oSLNKDWF = new ActiveXObject("SLNKDWF.About");
// myLog("Sleeping");
// oSLNKDWF.Sleep(1000 * 10);

        // Alles voor de eerste splitter slaan we over, dat is alleen commentaar
        var splitter = sqltekst.split("==splitter==");
        var linenr = 2 + (splitter[0].match(/\x0D\x0A/g) || []).length;
        for (var i = 1; i < splitter.length; i++)
        {
            var ll = (splitter[i].match(/\x0D\x0A/g) || []).length;
            myLog("Starting upgrade step {0} line {1}, {2} lines".format(i, linenr, ll));
            Oracle.Execute(splitter[i]);
            linenr += ll;
        }

        myLog("Done upgrade");
        myLog("Force settings reload");
        settings.loadSET(true); // Forceer caching opnieuw, doet zelf ook Application.Lock()/Unlock
        if (db_schema == Application("SET_" + customerId + "_DB_SCHEMA"))
            myLog("Schema version is still {0}".format(db_schema), "#f00");
        else
            myLog("Schema version is now {0}".format(Application("SET_" + customerId + "_DB_SCHEMA")));

        myLog("DBMS_UTILITY.COMPILE_SCHEMA just in case");
        Oracle.Execute("BEGIN DBMS_UTILITY.COMPILE_SCHEMA(USER, FALSE); END;");

        // Reset semafoor
        var sql = "UPDATE fac_version"
                + "   SET fac_version_upgrading = NULL"
                + " WHERE fac_version_upgrading = " + safe.quoted_sql(Session.SessionID) ;
        Oracle.Execute(sql);
    }
    myLog("Exit DBUPGRADE.asp");
%><% ASPPAGE_END(); %> 
