/*

Derby - Class org.apache.derbyTesting.functionTests.tests.upgradeTests.Changes10_10

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/
package org.apache.derbyTesting.functionTests.tests.upgradeTests;

import java.io.File;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import junit.framework.Test;
import org.apache.derbyTesting.functionTests.util.PrivilegedFileOpsForTests;
import org.apache.derbyTesting.junit.BaseTestSuite;
import org.apache.derbyTesting.junit.JDBC;
import org.apache.derbyTesting.junit.SupportFilesSetup;
import org.apache.derbyTesting.junit.TestConfiguration;


/**
 * Upgrade test cases for 10.10.
 */
public class Changes10_10 extends UpgradeChange
{
    ///////////////////////////////////////////////////////////////////////////////////
    //
    // CONSTANTS
    //
    ///////////////////////////////////////////////////////////////////////////////////

    private static  final   String  SYNTAX_ERROR = "42X01";
    private static  final   String  HARD_UPGRADE_REQUIRED = "XCL47";
    private static  final   String  NEEDS_JAVA_STYLE = "42ZCA";
    /**
    The readme file cautioning users against touching the files in
    the database directory 
    */
    private static final String DB_README_FILE_NAME = "README_DO_NOT_TOUCH_FILES.txt";

    ///////////////////////////////////////////////////////////////////////////////////
    //
    // STATE
    //
    ///////////////////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////////////////
    //
    // CONSTRUCTOR
    //
    ///////////////////////////////////////////////////////////////////////////////////

    public Changes10_10(String name)
    {
        super(name);
    }

    ///////////////////////////////////////////////////////////////////////////////////
    //
    // JUnit BEHAVIOR
    //
    ///////////////////////////////////////////////////////////////////////////////////
    
    /**
     * Return the suite of tests to test the changes made in 10.10.
     * @param phase an integer that indicates the current phase in
     *              the upgrade test.
     * @return the test suite created.
     */
    public static Test suite(int phase) {
        BaseTestSuite suite = new BaseTestSuite("Upgrade test for 10.9");

        suite.addTestSuite(Changes10_10.class);
        
        return new SupportFilesSetup((Test) suite);
    }

    ///////////////////////////////////////////////////////////////////////////////////
    //
    // TESTS
    //
    ///////////////////////////////////////////////////////////////////////////////////

    /**
     * Make sure that the following procedure(s) which are new to 10.10 are 
     *  only available after hard-upgrade
     *  1)invalidate stored statements 
     *    SYCS_UTIL.SYSCS_INVALIDATE_STORED_STATEMENTS
     */
    public  void    testProcsNewTo10_10()  throws Exception
    {
        Statement s = createStatement();
        String  iss = "call syscs_util.SYSCS_INVALIDATE_STORED_STATEMENTS()";
        String  rt = "call syscs_util.syscs_register_tool( 'foo', true )";
        String  rtGoodSQLState = "X0Y88";
        String  syntaxError = "42X01";
        boolean atLeastJava5 = JDBC.vmSupportsJDBC3();
        boolean oldSupportsBoolean = oldAtLeast( 10, 7 );

        switch ( getPhase() )
        {
        case PH_CREATE: // create with old version
        case PH_SOFT_UPGRADE: // boot with new version and soft-upgrade
        case PH_POST_SOFT_UPGRADE: // soft-downgrade: boot with old version after soft-upgrade
            vetProcs( s, iss, false, null );
            if ( atLeastJava5 )
            {
                vetProcs
                    ( s, rt, false,
                      oldSupportsBoolean || (getPhase() == PH_SOFT_UPGRADE ) ? null : syntaxError );
            }
            break;
            
        case PH_HARD_UPGRADE: // boot with new version and hard-upgrade
            vetProcs( s, iss, true, null );
            if ( atLeastJava5 ) { vetProcs( s, rt, true, rtGoodSQLState ); }
            break;
        }
        
        s.close();
    	
    }
    
    private void    vetProcs
        (
         Statement s,
         String procCall, 
         boolean shouldExist,
         String sqlState
         ) throws Exception
    {
        try {
            s.execute( procCall );
            
            if ( !shouldExist )
            {
                fail( "Procedure should not exist!"  );
            }
            if ( sqlState != null )
            {
                fail( "Expected to fail with SQLState " + sqlState );
            }
        } catch (SQLException se )
        {
            if ( sqlState == null ) { sqlState = "42Y03"; }
            assertSQLState( sqlState, se );
        }
    }

    /**
     * Verify upgrade behavior for user-defined aggregates.
     */
    public  void    testUDAs()  throws Exception
    {
        Statement st = createStatement();

        String  createUDA = "create derby aggregate mode for int external name 'foo.bar.Wibble'";
        String  dropUDA = "drop derby aggregate mode restrict";

        switch ( getPhase() )
        {
        case PH_CREATE: // create with old version
        case PH_POST_SOFT_UPGRADE: // soft-downgrade: boot with old version after soft-upgrade
            assertStatementError( SYNTAX_ERROR, st, createUDA );
            assertStatementError( SYNTAX_ERROR, st, dropUDA );
            break;
            
        case PH_SOFT_UPGRADE: // boot with new version and soft-upgrade
            assertStatementError( HARD_UPGRADE_REQUIRED, st, createUDA );
            assertStatementError( HARD_UPGRADE_REQUIRED, st, dropUDA );
            break;
            
        case PH_HARD_UPGRADE: // boot with new version and hard-upgrade
            st.execute( createUDA );
            st.execute( dropUDA );
            break;
        }
        
        st.close();
    }
    
    /**
     * Verify upgrade behavior for vararg routines.
     */
    public  void    testVarargss()  throws Exception
    {
        Statement st = createStatement();

        String  createVarargsProc = "create procedure vds ( a int ... ) language java parameter style derby no sql external name 'Foo.foo'";
        String  createVarargsFunc = "create function vds ( a int ... ) returns integer language java parameter style derby no sql external name 'Foo.foo'";
        String  createVarargsTableFunc = "create function vtf ( a int ... ) returns table ( b int ) language java parameter style derby_jdbc_result_set no sql external name 'Foo.foo'";
        String  createNonVarargsProcDerbyStyle = "create procedure nvds ( a int ) language java parameter style derby no sql external name 'Foo.foo'";
        String  createNonVarargsFuncDerbyStyle = "create function nvds ( a int ) returns integer language java parameter style derby no sql external name 'Foo.foo'";

        // table functions were introduced by 10.4
        boolean tableFunctionsOK = oldAtLeast( 10, 4 );       

        switch ( getPhase() )
        {
        case PH_CREATE: // create with old version
        case PH_POST_SOFT_UPGRADE: // soft-downgrade: boot with old version after soft-upgrade
            assertStatementError( SYNTAX_ERROR, st, createVarargsProc );
            assertStatementError( SYNTAX_ERROR, st, createVarargsFunc );
            if ( tableFunctionsOK ) { assertStatementError( SYNTAX_ERROR, st, createVarargsTableFunc ); }
            assertStatementError( SYNTAX_ERROR, st, createNonVarargsProcDerbyStyle );
            assertStatementError( SYNTAX_ERROR, st, createNonVarargsFuncDerbyStyle );
            break;
            
        case PH_SOFT_UPGRADE: // boot with new version and soft-upgrade
            assertStatementError( HARD_UPGRADE_REQUIRED, st, createVarargsProc );
            assertStatementError( HARD_UPGRADE_REQUIRED, st, createVarargsFunc );
            if ( tableFunctionsOK ) { assertStatementError( HARD_UPGRADE_REQUIRED, st, createVarargsTableFunc ); }
            assertStatementError( HARD_UPGRADE_REQUIRED, st, createNonVarargsProcDerbyStyle );
            assertStatementError( HARD_UPGRADE_REQUIRED, st, createNonVarargsFuncDerbyStyle );
            break;
            
        case PH_HARD_UPGRADE: // boot with new version and hard-upgrade
            st.execute( createVarargsProc );
            st.execute( createVarargsFunc );
            st.execute( createVarargsTableFunc );
            assertStatementError( NEEDS_JAVA_STYLE, st, createNonVarargsProcDerbyStyle );
            assertStatementError( NEEDS_JAVA_STYLE, st, createNonVarargsFuncDerbyStyle );
            break;
        }
        
        st.close();
    }
    
    /**
     * DERBY-5996(Create readme files (cautioning users against modifying 
     *  database files) at database hard upgrade time)
     * Simple test to make sure readme files are getting created
     */
    public void testReadMeFiles() throws SQLException, IOException
    {
        Statement s = createStatement();
        s.close();
        TestConfiguration currentConfig = TestConfiguration.getCurrent();
        String dbPath = currentConfig.getDatabasePath(currentConfig.getDefaultDatabaseName());
        switch (getPhase())
        {
        case PH_CREATE:
        case PH_SOFT_UPGRADE:
        case PH_POST_SOFT_UPGRADE:
            // DERBY-5995 Pre 10.10 databases would not have readme files
            lookForReadmeFile(dbPath, false);
            lookForReadmeFile(dbPath+File.separator+"seg0", false);
            lookForReadmeFile(dbPath+File.separator+"log", false);
            break;
        case PH_HARD_UPGRADE:
        case PH_POST_HARD_UPGRADE:
            // DERBY-5995 Hard upgrade to 10.10 will create readme files
            lookForReadmeFile(dbPath, true);
            lookForReadmeFile(dbPath+File.separator+"seg0", true);
            lookForReadmeFile(dbPath+File.separator+"log", true);
            break;
        }
    }

    /**
     * For pre-10.10 database, fileShouldExist will be false. For hard upgraded
     *  databases to 10.10, fileShouldExist will be true
     * @param path - this can be root database directory, log or seg0 directory
     * @param fileShouldExist
     * @throws IOException
     */
    private void lookForReadmeFile(String path, boolean fileShouldExist) throws IOException {
        File readmeFile = new File(path,
            DB_README_FILE_NAME);
        if (fileShouldExist)
        {
            assertTrue(readmeFile + "doesn't exist", 
                PrivilegedFileOpsForTests.exists(readmeFile));
        } else 
        {
            assertFalse(readmeFile + "exists", 
                PrivilegedFileOpsForTests.exists(readmeFile));
        
        }
    }

    // Old DB2 constants in Limits.java:
    // static final float DB2_SMALLEST_REAL = -3.402E+38f;
    // static final float DB2_LARGEST_REAL  = +3.402E+38f;
    // static final float DB2_SMALLEST_POSITIVE_REAL = +1.175E-37f;
    // static final float DB2_LARGEST_NEGATIVE_REAL  = -1.175E-37f;

    // static final double DB2_SMALLEST_DOUBLE = -1.79769E+308d;
    // static final double DB2_LARGEST_DOUBLE  = +1.79769E+308d;
    // static final double DB2_SMALLEST_POSITIVE_DOUBLE = +2.225E-307d;
    // static final double DB2_LARGEST_NEGATIVE_DOUBLE  = -2.225E-307d;

    static final float[] beyondDB2Real = new float[] {
        Float.MIN_VALUE,
        Float.MAX_VALUE,
        +1.174E-37f,
        -1.174E-37f,
        1.17549435E-38f, // Float.MIN_NORMAL
        -1.17549435E-38f // -Float.MIN_NORMAL
    };

    static final double[] beyondDB2Double = new double[] {
        Double.MIN_VALUE,
        Double.MAX_VALUE,
        +2.224E-307d,
        -2.224E-307d,
        2.2250738585072014E-308, // Double.MIN_NORMAL
        -2.2250738585072014E-308 // -Double.MIN_NORMAL
    };

    /**
     * Verify upgrade behavior DERBY-3398: removing DB2 float limits
     */
    public  void    testFloatLimits()  throws Exception
    {
        Statement st = createStatement();
        st.execute("create table d3398(r real, d double)");

        PreparedStatement psInsertReal =
            prepareStatement("insert into d3398(r) values (?)");
        PreparedStatement psInsertDouble =
            prepareStatement("insert into d3398(d) values (?)");
        PreparedStatement psSelect =
            prepareStatement("select * from d3398",
                ResultSet.TYPE_FORWARD_ONLY,
                ResultSet.CONCUR_UPDATABLE);

        st.execute("insert into d3398 values (0.0, 0.0)");


        switch ( getPhase() )
        {
        case PH_CREATE: // create with old version
            verifyDB2Behavior(psSelect, psInsertReal, psInsertDouble, false);

            break;
        case PH_POST_SOFT_UPGRADE: // soft-downgrade: boot with old
                                   // version after soft-upgrade
            verifyDB2Behavior(psSelect, psInsertReal, psInsertDouble, false);

            break;
        case PH_SOFT_UPGRADE: // boot with new version and soft-upgrade

            verifyDB2Behavior(psSelect, psInsertReal, psInsertDouble, true);

            break;
        case PH_HARD_UPGRADE: // boot with new version and hard-upgrade

            for (int i = 0; i < beyondDB2Real.length; i++) {
                psInsertReal.setFloat(1, beyondDB2Real[i]);
                psInsertReal.execute();

                ResultSet rs = psSelect.executeQuery();
                rs.next();
                rs.updateFloat(1, beyondDB2Real[i]);
                rs.updateRow();
                rs.close();
            }

            for (int i = 0; i < beyondDB2Double.length; i++) {
                psInsertDouble.setDouble(1, beyondDB2Double[i]);
                psInsertDouble.execute();

                ResultSet rs = psSelect.executeQuery();
                rs.next();
                rs.updateDouble(2, beyondDB2Double[i]);
                rs.updateRow();
                rs.close();
            }

            break;
        }

        st.executeUpdate("drop table d3398");
        st.close();
    }

    private void assertSetError(PreparedStatement ps, float fv, boolean defer)
            throws SQLException {
        try {
            ps.setFloat(1, fv);

            if (!defer) {
                fail();
            }

            ps.executeUpdate();
            fail();
        } catch (SQLException e) {
            assertSQLState("22003", e);
        }
    }
    
    private void assertSetError(PreparedStatement ps, double dv, boolean defer)
            throws SQLException {
        try {
            ps.setDouble(1, dv);

            if (!defer) {
                fail();
            }

            ps.executeUpdate();
            fail();
        } catch (SQLException e) {
            assertSQLState("22003", e);
        }
    }


    private void assertUpdateError(
            PreparedStatement ps,
            float fv,
            boolean defer) throws SQLException {

        boolean supportsForwardUpdatableResultSet = oldAtLeast( 10, 2 );

        if (!supportsForwardUpdatableResultSet) {
            return;
        }

        ResultSet rs = ps.executeQuery();
        rs.next();

        try {
            rs.updateFloat(1, fv);

            if (!defer) {
                fail();
            }

            rs.updateRow();
            fail();
        } catch (SQLException e) {
            assertSQLState("22003", e);
        } finally {
            rs.close();
        }
    }

    private void assertUpdateError(
            PreparedStatement ps,
            double fv,
            boolean defer) throws SQLException {

        boolean supportsForwardUpdatableResultSet = oldAtLeast( 10, 2 );

        if (!supportsForwardUpdatableResultSet) {
            return;
        }

        ResultSet rs = ps.executeQuery();
        rs.next();

        try {
            rs.updateDouble(1, fv);

            if (!defer) {
                fail();
            }

            rs.updateRow();
            fail();
        } catch (SQLException e) {
            assertSQLState("22003", e);
        } finally {
            rs.close();
        }
    }

    /**
     * Check that the old DB2 limits are (still) enforced.
     *
     * @param defer In soft upgrade mode, the checking if deferred after
     * DERBY-3398, i.e. instead of throwing on the DB2 limits when calling
     * {@code ResultSet#updateXXX} or {@code PreparedStatement#setXXX}, the
     * check throws on {@code ResultSet#updateRow}, or {#insertRow}, and
     * similarly on {@code PreparedStatement#execute} or {@code #executeUpdate}.
     *
     * @throws SQLException if we see some expected error.
     */
    private void verifyDB2Behavior (
            PreparedStatement psSelect,
            PreparedStatement psInsertReal,
            PreparedStatement psInsertDouble,
            boolean defer) throws SQLException {

        for (int i = 0; i < beyondDB2Real.length; i++) {
            assertSetError(psInsertReal, beyondDB2Real[i], defer);
            assertUpdateError(psSelect, beyondDB2Real[i], defer);
        }

        for (int i = 0; i < beyondDB2Double.length; i++) {
            assertSetError(psInsertDouble, beyondDB2Double[i], defer);
            assertUpdateError(psSelect, beyondDB2Double[i], defer);
        }
    }
}
