Package org.nutz.dao.impl.sql

Source Code of org.nutz.dao.impl.sql.NutSql

package org.nutz.dao.impl.sql;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import org.nutz.dao.Condition;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.jdbc.Jdbcs;
import org.nutz.dao.jdbc.ValueAdaptor;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.sql.SqlCallback;
import org.nutz.dao.sql.VarIndex;
import org.nutz.dao.sql.VarSet;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;

public class NutSql extends NutStatement implements Sql {

  SqlLiteral literal;

  private VarSet vars;

  private List<VarSet> rows;

  private VarSet lastRow;

  private SqlCallback callback;

  private ValueAdaptor[] adaptors;

  private ValueAdaptor[] clientAdaptors;

  private NutSql() {
    super();
    vars = new SimpleVarSet();
    rows = new LinkedList<VarSet>();
    this.addBatch();
  }

  public NutSql(String sql) {
    this();
    this.literal = new SqlLiteral().valueOf(sql);
    this.setSqlType(this.literal.getType());
    // 根据字面量,构造一个参数的适配器数组
    adaptors = new ValueAdaptor[literal.getParamIndexes().getOrders().size()];
    clientAdaptors = new ValueAdaptor[adaptors.length];
  }

  private NutSql(SqlLiteral literal, SqlCallback callback) {
    this();
    this.literal = literal;
    this.setSqlType(this.literal.getType());
    this.callback = callback;
    // 根据字面量,构造一个参数的适配器数组
    adaptors = new ValueAdaptor[literal.getParamIndexes().getOrders().size()];
    clientAdaptors = new ValueAdaptor[adaptors.length];
  }

  public Sql setEntity(Entity<?> en) {
    return (Sql) super.setEntity(en);
  }

  public ValueAdaptor[] getAdaptors() {
    for (int i = 0; i < adaptors.length; i++) {
      // 采用用户的设定
      if (null != clientAdaptors[i])
        adaptors[i] = clientAdaptors[i];
      // 自动决定
      else if (null == adaptors[i]) {
        // 获得对应参数的名称,以及关联的其他索引
        String name = literal.getParamIndexes().getOrderName(i);
        int[] is = literal.getParamIndexes().getOrderIndex(name);
        // 寻找第一个非 null 的参数
        Object value = null;
        for (VarSet row : rows) {
          value = row.get(name);
          if (null != value)
            break;
        }
        // 找到了,得到适配器,然后循环设置一下
        if (null != value) {
          ValueAdaptor vab = Jdbcs.getAdaptor(Mirror.me(value));
          for (int x : is)
            adaptors[x] = vab;
        }
        // 如果找不到用 Null 适配器
        else {
          adaptors[i] = Jdbcs.Adaptor.asNull;
        }

      }
    }
    return adaptors;
  }

  public void setValueAdaptor(String name, ValueAdaptor adaptor) {
    int[] is = literal.getParamIndexes().getOrderIndex(name);
    if (null != is)
      for (int i : is)
        adaptors[i] = adaptor;
  }

  public Object[][] getParamMatrix() {
    Object[][] re = new Object[rows.size()][adaptors.length];
    int i = 0;
    for (VarSet row : rows) {
      Object[] cols = re[i++];
      for (String name : literal.getParamIndexes().names()) {
        Object value = row.get(name);
        int[] is = literal.getParamIndexes().getOrderIndex(name);
        for (int x : is)
          cols[x] = value;
      }
    }
    return re;
  }

  public String toPreparedStatement() {
    String[] ss = _createSqlElements();

    // 填充参数
    VarIndex vIndex = literal.getParamIndexes();
    for (String name : vIndex.names()) {
      int[] is = vIndex.indexesOf(name);
      for (int i : is)
        ss[i] = "?";

    }
    return Lang.concat(ss).toString();
  }

  /**
   * 获取语句模板并填充占位符
   *
   * @return 语句模板
   */
  private String[] _createSqlElements() {
    String[] ss = literal.stack.cloneChain();
    VarIndex vIndex = literal.getVarIndexes();
    VarSet vs = vars;
    for (String name : vIndex.names()) {
      int[] is = vIndex.indexesOf(name);
      Object obj = vs.get(name);
      for (int i : is)
        ss[i] = null == obj ? "" : obj.toString();
    }
    return ss;
  }

  public VarSet vars() {
    return vars;
  }

  public VarSet params() {
    return lastRow;
  }

  public VarIndex varIndex() {
    return literal.getVarIndexes();
  }

  public VarIndex paramIndex() {
    return literal.getParamIndexes();
  }

  public void addBatch() {
    lastRow = new SimpleVarSet();
    rows.add(lastRow);
  }

  public void clearBatch() {
    rows.clear();
    addBatch();
  }

  public Sql setCallback(SqlCallback callback) {
    this.callback = callback;
    return this;
  }

  public Sql setCondition(Condition cnd) {
    this.vars().set("condition", cnd.toSql(this.getEntity()));
    return this;
  }

  public Sql duplicate() {
    return new NutSql(literal, callback);
  }

  public void onBefore(Connection conn) {}

  public void onAfter(Connection conn, ResultSet rs) throws SQLException {
    if (null != callback)
      getContext().setResult(callback.invoke(conn, rs, this));
  }

  @Override
  public String toString() {
    /*
     * // 语句模板 String[] ss = _createSqlElements();
     *
     * // 填充参数 VarIndex vIndex = literal.getParamIndexes(); VarSet vs =
     * rows.get(0); for (String name : vIndex.names()) { int[] is =
     * vIndex.indexesOf(name); String s =
     * Sqls.formatFieldValue(vs.get(name)).toString(); for (int i : is)
     * ss[i] = s; }
     *
     * return Lang.concat(ss).toString();
     */
    return super.toStatement(this.getParamMatrix(), this.toPreparedStatement());
  }

}
TOP

Related Classes of org.nutz.dao.impl.sql.NutSql

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.