/*
 * 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.parser.mssql;

import com.queplix.core.jxb.entity.Efield;
import com.queplix.core.jxb.entity.Entity;
import com.queplix.core.jxb.entity.types.SqlSType;
import com.queplix.core.modules.config.utils.EntityHelper;
import com.queplix.core.modules.eql.EQLObject;
import com.queplix.core.modules.eql.EQLReq;
import com.queplix.core.modules.eql.EQLReqField;
import com.queplix.core.modules.eql.EQLResCell;
import com.queplix.core.modules.eql.error.EQLException;
import com.queplix.core.modules.eql.error.EQLSystemException;
import com.queplix.core.modules.eql.parser.generic.SQLExecutorGenericImpl;
import com.queplix.core.utils.sql.vendor.mssql.MssqlText;

import java.sql.SQLException;

/**
 * <p>SQL executor MS SQL 2000 implementation class</p>
 *
 * @author [ALB] Baranov Andrey
 * @version $Revision: 1.2 $ $Date: 2006/05/26 12:58:12 $
 */

public class SQLExecutorMssqlImpl
        extends SQLExecutorGenericImpl {

    /*
     * No javadoc
     * @see SQLExecutorGenericImpl#getCell
     */
    protected EQLResCell getCell(EQLReq req,
                                 EQLReqField reqField,
                                 ResultSetCursor cursor)
            throws EQLException {

        Efield field = reqField.getField();
        int sql_type = field.getSqltype().getType();
        boolean isDistinct = req.getSelect().isDistinct();

        //
        // MSSQL doesn't support TEXT fields in queries witd word DISTINCT!!!
        //
        if(isDistinct && (sql_type == SqlSType.MEMO_TYPE
                || sql_type == SqlSType.MEMO_LONG_TYPE)) {
            // retrive DATALENGTH() and TEXTPTR()
            Object o = null;
            Integer size = null;

            try {
                size = sqlWrapper.getIntParser().getValue(cursor.rs(),
                        cursor.next());
            } catch (SQLException ex) {
                throw new EQLSystemException(ex);
            }

            if(size != null) {
                // size is not NULL - retrive data
                Entity entity = reqField.getReqEntity().getEntity();
                String tableName = entity.getDbobject();
                String columnName = EntityHelper.getFieldFullName(null,
                        field.getName());
                try {
                    o = MssqlText.getObject(cursor.rs(), cursor.next(),
                            tableName, columnName, size.intValue());
                } catch (SQLException ex) {
                    throw new EQLSystemException(ex);
                }

            } else {
                // size is NULL - scroll cursor only
                cursor.next();
            }

            return new EQLResCell(reqField, EQLObject.getInstance(o));
        }

        // common situation
        return super.getCell(req, reqField, cursor);
    }

    /*
     * No javadoc
     * @see SQLExecutorGenericImpl#getLazyCell
     */
    protected EQLResCell getLazyCell(EQLReq req,
                                     EQLReqField reqField,
                                     ResultSetCursor cursor)
            throws EQLException {

        Efield field = reqField.getField();
        int sql_type = field.getSqltype().getType();

        if(sql_type == SqlSType.MEMO_LONG_TYPE) {
            try {
                Object o = sqlWrapper.getParser(sql_type).getObject(cursor.rs(),
                        cursor.next());
                return new EQLResCell(reqField, EQLObject.getInstance(o));
            } catch (SQLException ex) {
                throw new EQLSystemException(ex);
            }
        } else if(sql_type == SqlSType.MEMO_TYPE ||
                sql_type == SqlSType.BINARY_TYPE) {

            // read DATALENGTH()
            try {
                Integer len = sqlWrapper.getIntParser().getValue(cursor.rs(),
                        cursor.next());
                return new EQLResCell(reqField,
                        (len == null || len.intValue() <= 0));
            } catch (SQLException ex) {
                throw new EQLSystemException(ex);
            }
        } else {
            // read 0 or 1
            try {
                Integer isNull = sqlWrapper.getIntParser().getValue(cursor.rs(),
                        cursor.next());
                return new EQLResCell(reqField, isNull.intValue() == 0);
            } catch (SQLException ex) {
                throw new EQLSystemException(ex);
            }
        }
    }
}
