/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.performance.reading;

import java.util.*;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.testing.models.performance.toplink.*;
import org.eclipse.persistence.testing.framework.*;

/**
 * This test compares the performance of read object vs using parameterized SQL.
 */
public class ReadObjectvsParameterizedSQLTest extends PerformanceComparisonTestCase {
    protected Employee employee;
    protected ReadObjectQuery bindQuery;
    protected ReadObjectQuery query;

    public ReadObjectvsParameterizedSQLTest() {
        setDescription("This test compares the performance of read object vs using parameterized SQL.");
        addReadObjectSameQueryTest();
        addReadObjectParameterizedSQLTest();
        addReadObjectParameterizedSQLSameQueryTest();
        addReadObjectPreparedStatementTest();
        addReadObjectDynamicTest();
    }

    /**
     * Find any employee.
     */
    @Override
    public void setup() {
        employee = (Employee)getSession().readObject(Employee.class);

        bindQuery = new ReadObjectQuery(Employee.class);
        ExpressionBuilder builder = new ExpressionBuilder();
        bindQuery.setSelectionCriteria(builder.get("firstName").equal(builder.getParameter("firstName")).and(builder.get("lastName").equal(builder.getParameter("lastName"))));
        bindQuery.addArgument("firstName");
        bindQuery.addArgument("lastName");
        bindQuery.bindAllParameters();
        bindQuery.cacheStatement();

        query = new ReadObjectQuery(Employee.class);
        builder = new ExpressionBuilder();
        query.setSelectionCriteria(builder.get("firstName").equal(builder.getParameter("firstName")).and(builder.get("lastName").equal(builder.getParameter("lastName"))));
        query.addArgument("firstName");
        query.addArgument("lastName");
    }

    /**
     * Read object.
     */
    @Override
    public void test() throws Exception {
        getSession().getIdentityMapAccessor().removeFromIdentityMap(employee);
        ReadObjectQuery query = new ReadObjectQuery(Employee.class);
        ExpressionBuilder builder = new ExpressionBuilder();
        query.setSelectionCriteria(builder.get("firstName").equal(employee.getFirstName()).and(builder.get("lastName").equal(employee.getLastName())));
        getSession().executeQuery(query);
    }

    /**
     * Read object using same query.
     */
    public void addReadObjectSameQueryTest() {
        PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
            @Override
            public void test() {
                getSession().getIdentityMapAccessor().removeFromIdentityMap(employee);
                Vector arguments = new Vector(2);
                arguments.add(employee.getFirstName());
                arguments.add(employee.getLastName());
                getSession().executeQuery(query, arguments);
            }
        };
        test.setName("ReadObjectSameQueryTest");
        //test.setAllowableDecrease(5); - should be about same now because of expression parse cache
        addTest(test);
    }

    /**
     * Read object using param SQL.
     */
    public void addReadObjectParameterizedSQLTest() {
        PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
            @Override
            public void test() {
                getSession().getIdentityMapAccessor().removeFromIdentityMap(employee);
                ReadObjectQuery query = new ReadObjectQuery(Employee.class);
                ExpressionBuilder builder = new ExpressionBuilder();
                query.setSelectionCriteria(builder.get("firstName").equal(employee.getFirstName()).and(builder.get("lastName").equal(employee.getLastName())));
                query.bindAllParameters();
                query.cacheStatement();
                getSession().executeQuery(query);
            }
        };
        test.setName("ReadObjectParameterizedSQLTest");
        test.setAllowableDecrease(30);
        addTest(test);
    }

    /**
     * Read object using param SQL using same query.
     */
    public void addReadObjectParameterizedSQLSameQueryTest() {
        PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
            @Override
            public void test() {
                getSession().getIdentityMapAccessor().removeFromIdentityMap(employee);
                Vector arguments = new Vector(2);
                arguments.add(employee.getFirstName());
                arguments.add(employee.getLastName());
                getSession().executeQuery(bindQuery, arguments);
            }
        };
        test.setName("ReadObjectParameterizedSQLSameQueryTest");
        test.setAllowableDecrease(40);
        addTest(test);
    }

    /**
     * Read object using old prepared statements.
     */
    public void addReadObjectPreparedStatementTest() {
        PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
            @Override
            public void test() {
                DatabaseAccessor.shouldUseDynamicStatements = false;
                getSession().getIdentityMapAccessor().removeFromIdentityMap(employee);
                ReadObjectQuery query = new ReadObjectQuery(Employee.class);
                query.dontBindAllParameters();
                ExpressionBuilder builder = new ExpressionBuilder();
                query.setSelectionCriteria(builder.get("firstName").equal(employee.getFirstName()).and(builder.get("lastName").equal(employee.getLastName())));
                getSession().executeQuery(query);
                DatabaseAccessor.shouldUseDynamicStatements = true;
            }
        };
        test.setName("ReadObjectPreparedStatementTest");
        test.setAllowableDecrease(-30);
        addTest(test);
    }

    /**
     * Read object using binding only.
     */
    public void addReadObjectDynamicTest() {
        PerformanceComparisonTestCase test = new PerformanceComparisonTestCase() {
            @Override
            public void test() {
                getSession().getIdentityMapAccessor().removeFromIdentityMap(employee);
                ReadObjectQuery query = new ReadObjectQuery(Employee.class);
                ExpressionBuilder builder = new ExpressionBuilder();
                query.setSelectionCriteria(builder.get("firstName").equal(employee.getFirstName()).and(builder.get("lastName").equal(employee.getLastName())));
                query.dontBindAllParameters();
                getSession().executeQuery(query);
            }
        };
        test.setName("ReadObjectDynamicTest");
        test.setAllowableDecrease(-20);
        addTest(test);
    }
}
