package org.beetl.sql.core.db;

import org.beetl.sql.core.range.RangeSql;

import java.text.MessageFormat;
import java.util.Map;

/**
 * 数据库差异：h2.
 *
 * @author zhoupan
 */
public class DerbyStyle extends AbstractDBStyle {

    RangeSql rangeSql = null;
    public DerbyStyle() {
        super();
        rangeSql = new DerbyRowNumRange(this);
    }

    public String getPageSQL(String sql) {
        return sql + this.getOrderBy() + " \nlimit " + sqlTemplateEngine.appendVar(DBAutoGeneratedSql.OFFSET)+ " , " + sqlTemplateEngine.appendVar(DBAutoGeneratedSql.PAGE_SIZE);
    }


    @Override
    public String getName() {
        return "derby";
    }

    @Override
    public int getDBType() {
        return DBType.DB_DERBY;
    }

    @Override
    public RangeSql getRangeSql() {
        return rangeSql;
    }



    public class DerbyRowNumRange implements RangeSql {
        AbstractDBStyle dbStyle = null;
        String jdbcTemplate = "SELECT * FROM ( SELECT ROW_NUMBER() OVER() AS beetl_rn, " +
                "mytable.* FROM ({0}) mytable) AS tmp WHERE beetl_rn <= {1} and beetl_rn>{2}";
        public DerbyRowNumRange(AbstractDBStyle dbStyle){
            this.dbStyle = dbStyle;
        }



        @Override
        public String toRange(String jdbcSql, Object objOffset, Long limit) {
            Long offset = ((Number)objOffset).longValue();
            offset = PageParamKit.oracleOffset(dbStyle.offsetStartZero, offset);
            long pageEnd = PageParamKit.oraclePageEnd(offset, limit);
            String sql = MessageFormat.format(jdbcTemplate,jdbcSql,pageEnd,offset);
            return sql;
        }

        @Override
        public String toTemplateRange(Class mapping,String template) {

            String pageSql = MessageFormat.format(jdbcTemplate,template,
                    dbStyle.appendExpress(DBAutoGeneratedSql.PAGE_END ),
                    dbStyle.appendExpress(DBAutoGeneratedSql.OFFSET ));

            return pageSql;
        }

        @Override
        public void addTemplateRangeParas(Map<String, Object> paras, Object objOffset, long size) {
            Long offset = (Long)objOffset;
            long s = offset + (dbStyle.offsetStartZero ? 1 : 0);
            paras.put(DBAutoGeneratedSql.OFFSET, s);
            paras.put(DBAutoGeneratedSql.PAGE_END, s + size);
        }
    }


}
