Package net.paoding.rose.jade.statement.expression.impl

Source Code of net.paoding.rose.jade.statement.expression.impl.ExqlContextImpl

package net.paoding.rose.jade.statement.expression.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;

import net.paoding.rose.jade.statement.expression.ExqlContext;
import net.paoding.rose.jade.statement.expression.util.ExqlUtils;

/**
* 实现简单的输出上下文。
*
* @author han.liao
*/
public class ExqlContextImpl implements ExqlContext  {

    // 输出的常量
    private static final String NULL = "NULL";

    private static final char QUESTION = '?';

    private static final char COMMA = ',';

    // 参数列表
    protected final ArrayList<Object> params = new ArrayList<Object>();

    // 输出缓冲区
    protected final StringBuilder builder;

    /**
     * 构造上下文对象。
     *
     * @param capacity - 缓存的容量
     */
    public ExqlContextImpl(int capacity) {
        builder = new StringBuilder(capacity);
    }

    @Override
    public Object[] getParams() {
        return params.toArray();
    }

    @Override
    public void fillChar(char ch) {
        builder.append(ch);
    }

    @Override
    public void fillText(String string) {

        // 直接输出字符串
        builder.append(string);
    }

    @Override
    public void fillValue(Object obj) {

        if (obj instanceof Collection<?>) {

            // 展开  Collection 容器, 输出逗号分隔以支持 IN (...) 语法
            // "IN (:varlist)" --> "IN (?, ?, ...)"
            fillCollection((Collection<?>) obj);

        } else if ((obj != null) && obj.getClass().isArray() && obj.getClass() != byte[].class) {

            // 用数组构造  Collection 容器
            fillCollection(ExqlUtils.asCollection(obj));

        } else {

            // 直接输出参数, "uid > :var" --> "uid > ?"
            setParam(obj);

            builder.append(QUESTION);
        }
    }

    @Override
    public String flushOut() {
        return builder.toString();
    }

    @Override
    public String toString() {
        return flushOut();
    }

    /**
     * 设置参数的内容。
     *
     * @param value - 参数的内容
     */
    protected void setParam(Object value) {
        params.add(value);
    }

    /**
     * 输出集合对象到语句内容, 集合将被展开成 IN (...) 语法。
     *
     * PS: IN :varlist --> IN (?, ?, ...)
     *
     * @param collection - 输出的集合
     */
    private void fillCollection(Collection<?> collection) {

        int count = 0;

        // 展开  Collection 容器, 输出逗号分隔以支持 IN (...) 语法
        // "IN :varlist" --> "IN (?, ?, ...)"
        if (collection.isEmpty()) {

            // 输出  "IN (NULL)" 保证不会产生错误
            builder.append(NULL);

        } else {

            // 输出逗号分隔的参数表
            for (Object value : collection) {

                if (value != null) {

                    if (count > 0) {
                        builder.append(COMMA);
                    }

                    // 输出参数内容
                    setParam(value);

                    builder.append(QUESTION);

                    count++;
                }
            }
        }
    }

    //--------------

    // 进行简单测试
    public static void main(String... args) throws Exception {

        ExqlContext context = new ExqlContextImpl(1024);

        context.fillText("WHERE uid = ");
        context.fillValue(102);
        context.fillText(" AND sid IN (");
        context.fillValue(new int[] { 11, 12, 24, 25, 31, 32, 33 });
        context.fillText(") AND (create_time > ");
        context.fillValue(new Date());
        context.fillText(" OR create_time <= ");
        context.fillValue(new Date());
        context.fillChar(')');

        System.out.println(context.flushOut());
        System.out.println(Arrays.toString(context.getParams()));
    }
}
TOP

Related Classes of net.paoding.rose.jade.statement.expression.impl.ExqlContextImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.