/*
 * Copyright 2006-2007 Queplix Corp.
 *
 * Licensed under the Queplix Public License, Version 1.1.1 (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.queplix.com/solutions/commercial-open-source/queplix-public-license/
 *
 * 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 com.queplix.core.modules.eql.funcs;

import com.queplix.core.error.GenericSystemException;
import com.queplix.core.jxb.entity.Entity;
import com.queplix.core.modules.config.utils.EntitySchema;
import com.queplix.core.modules.config.utils.db.DBEntitySchema;
import com.queplix.core.modules.eql.EQLNumberObject;
import com.queplix.core.modules.eql.EQLReqFuncExecutable;
import com.queplix.core.modules.eql.EQLReqOp;
import com.queplix.core.modules.eql.EQLReqSubOpMember;
import com.queplix.core.modules.eql.EQLReqSubOpMemberFunc;
import com.queplix.core.modules.eql.EQLStringObject;
import com.queplix.core.modules.eql.error.EQLException;
import com.queplix.core.modules.eql.error.EQLFunctionParseException;
import com.queplix.core.modules.eql.parser.EQLAgent;
import com.queplix.core.modules.eql.parser.EQLAgentFactory;
import com.queplix.core.utils.sql.SqlWrapper;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * <p>Next Sequence Function Implementation</p>
 *
 * @author Baranov Andrey [ALB]
 * @version $Revision: 1.1.1.1 $ $Date: 2005/09/12 15:30:25 $
 */

public final class NextSeqFunc
        extends EQLReqSubOpMemberFunc implements EQLReqFuncExecutable {

    /*
     * No javadoc
     * @see EQLReqFuncExecutable#execute
     */
    public EQLReqSubOpMember execute()
            throws EQLException {

        //
        // Get function parameters:
        //
        // 1: entity name
        // 2: sequence name
        //
        EQLReqOp reqOp1 = getParameter(0);
        if(reqOp1 == null) {
            throw new EQLFunctionParseException(this);
        }

        EQLReqOp reqOp2 = getParameter(1);
        if(reqOp2 == null) {
            throw new EQLFunctionParseException(this);
        }

        String entityName;
        try {
            EQLStringObject subOpMember = (EQLStringObject) reqOp1.getSubOp(0)
                    .getMember();
            entityName = subOpMember.getValue();
        } catch (Exception ex) {
            throw new EQLFunctionParseException(this, ex);
        }

        String seqName;
        try {
            EQLStringObject subOpMember = (EQLStringObject) reqOp2.getSubOp(0)
                    .getMember();
            seqName = subOpMember.getValue();
        } catch (Exception ex) {
            throw new EQLFunctionParseException(this, ex);
        }

        // get entity
        Entity entity = eqlInt.getSession().findEntity(entityName);

        // get SqlWrapper - use entity schema
        EQLAgent eqlAgent = EQLAgentFactory.getInstance().getEQLAgent(entity);
        EntitySchema entitySchema = eqlAgent.getEntitySchema();
        if(!(entitySchema instanceof DBEntitySchema)) {
            throw new IllegalStateException("Only DB entity schemas supported");
        }
        SqlWrapper sqlW = ((DBEntitySchema) entitySchema).getSqlWrapper();

        // get next sequence
        long next_seq;
        Connection con = null;
        try {
            con = sqlW.doConnection();
            next_seq = sqlW.getNextSeq(con, seqName);

        } catch (SQLException ex) {
            throw new GenericSystemException(
                    "SQL exception: " + ex.getMessage(), ex);

        } finally {
            sqlW.closeConnection(con);
        }

        return new EQLNumberObject(new Long(next_seq));
    }
}
