/*
 * Copyright (c) 2012, 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:
//     Vikram Bhatia - initial
package org.eclipse.persistence.testing.tests.queries;

import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.sessions.server.*;

/**
 * This test verifies if a transaction is committed while using read &amp; write
 * connections in same client session with cursored stream used in read.
 */
public class CursoredStreamReadWriteClientSessionTest extends TestCase {
    protected Server serverSession;
    protected ClientSession clientSession;
    protected int addressId = 0;
    protected Exception caughtException = null;

    /**
     * CursoredStreamReadWriteClientSessionTest constructor.
     */
    public CursoredStreamReadWriteClientSessionTest() {
        setDescription("Verifies if a transaction is committed while using read &amp; write connections in same client session with cursored stream used in read.");
    }

    @Override
    public void reset() {
        this.clientSession.release();
        this.serverSession.logout();
    }

    @Override
    public void setup() {
        org.eclipse.persistence.sessions.Project proj =
            new org.eclipse.persistence.testing.models.employee.relational.EmployeeProject();
        proj.setDatasourceLogin(getSession().getDatasourceLogin().clone());

        // Set initial &amp; min size of connection in pool to ZERO.
        this.serverSession = proj.createServerSession(0, 0, 1);
        this.serverSession.setSessionLog(getSession().getSessionLog());
        this.serverSession.login();
        this.clientSession = this.serverSession.acquireClientSession();

        // Fetch a address Id from database.
        Employee emp = (Employee) getSession().readObject(Employee.class);
        this.addressId = emp.getAddress().getId().intValue();
    }

    @Override
    public void test() {
        clientSession.beginTransaction();
        try {
            // Fetch Address object to update.
            ReadObjectQuery objquery = new ReadObjectQuery();
            objquery.setReferenceClass(Address.class);
            ExpressionBuilder objquerybuilder = new ExpressionBuilder();
            Expression objexpr = objquerybuilder.get("id").equal(this.addressId);
            objquery.setSelectionCriteria(objexpr);

            Address address = (Address) clientSession.executeQuery(objquery);
            // This seems to be a very bad test, it is corrupting the database state,
            // Changing the address is not required anyway as this test does no verify,
            // and since it is not using a UnitOfWork, the update will update verything anyway.
            //address.setStreet("Lawrence Street");

            UpdateObjectQuery updateQuery = new UpdateObjectQuery();
            updateQuery.setObject(address);
            clientSession.executeQuery(updateQuery);

            ReadAllQuery query = new ReadAllQuery();
            query.setReferenceClass(Employee.class);
            query.useCursoredStream(1, 1);

            CursoredStream stream = (CursoredStream)clientSession.executeQuery(query);
            Object result = null;
            while (stream.hasNext()) {
                result = stream.next();
            }
            clientSession.commitTransaction();
        } catch(Exception ex) {
            caughtException = ex;
        } finally {
            try {
                clientSession.rollbackTransaction();
            } catch (Exception ex) {
                // ignore
            }
        }
    }

    @Override
    public void verify() {
        if (caughtException == null) {
            return;
        }

        if (caughtException instanceof DatabaseException) {
            throw new TestErrorException("incorrect if the exception is thrown due to a closed connection");
        }
    }
}

