package org.nutz.dao.impl.jdbc;
import java.lang.reflect.Array;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.nutz.dao.Chain;
import org.nutz.dao.entity.Entity;
import org.nutz.dao.impl.sql.NutStatement;
import org.nutz.dao.jdbc.ValueAdaptor;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.sql.PItem;
import org.nutz.dao.sql.Pojo;
import org.nutz.dao.sql.PojoCallback;
import org.nutz.dao.sql.SqlType;
import org.nutz.dao.util.Pojos;
import org.nutz.lang.Lang;
public class NutPojo extends NutStatement implements Pojo {
private PojoCallback before;
private PojoCallback after;
/**
* 参数表
*/
private LinkedList<Object> params;
/**
* 缓存语句共包括的参数数量
*/
private int _pmnum;
/**
* 当前操作对象
*/
private Object obj;
/**
* 供子类访问的语句元素
*/
protected ArrayList<PItem> items;
public NutPojo() {
super();
params = new LinkedList<Object>();
items = new ArrayList<PItem>(6);
_pmnum = -1;
append(Pojos.Items.sqlType());
}
public ValueAdaptor[] getAdaptors() {
ValueAdaptor[] adaptors = new ValueAdaptor[_params_count()];
int i = 0;
for (PItem item : items)
i = item.joinAdaptor(getEntity(), adaptors, i);
return adaptors;
}
public Object[][] getParamMatrix() {
Object[][] re;
/*
* 木有参数对象,但是有参数,循环一下,看看元素们会给出什么样的参数
*/
if (_params_count() > 0 && params.isEmpty()) {
re = new Object[1][_params_count()];
int i = 0;
for (PItem item : items)
i = item.joinParams(getEntity(), null, re[0], i);
}
/*
* 依照参数列表循环获取参数矩阵
*/
else {
re = new Object[params.size()][_params_count()];
int row = 0;
for (Object obj : params) {
int i = 0;
for (PItem item : items)
i = item.joinParams(getEntity(), obj, re[row], i);
row++;
}
}
return re;
}
public String toPreparedStatement() {
StringBuilder sb = new StringBuilder();
for (PItem item : items)
item.joinSql(getEntity(), sb);
return sb.toString();
}
public void onBefore(Connection conn) throws SQLException {
if (null != before)
before.invoke(conn, null, this);
}
public void onAfter(Connection conn, ResultSet rs) throws SQLException {
if (null != after)
getContext().setResult(after.invoke(conn, rs, this));
}
public Pojo setBefore(PojoCallback before) {
this.before = before;
return this;
}
public Pojo setAfter(PojoCallback after) {
this.after = after;
return this;
}
public Pojo setPager(Pager pager) {
this.getContext().setPager(pager);
return this;
}
public Pojo addParamsBy(Object obj) {
if (null == obj)
return this;
// 集合
if (obj instanceof Collection<?>)
for (Object ele : (Collection<?>) obj)
addParamsBy(ele);
// 数组
else if (obj.getClass().isArray()) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++)
addParamsBy(Array.get(obj, i));
}
// 链: 变成 Map
else if (obj instanceof Chain)
params.add(((Chain) obj).updateBy(this.getEntity()).toMap());
// 迭带器 : TODO 以后是不是考虑 params 也变成迭代器,这样可以允许无限多的对象被执行 ...
else if (obj instanceof Iterator<?>) {
Iterator<?> it = (Iterator<?>) obj;
while (it.hasNext())
addParamsBy(it.next());
}
// 其他对象,直接保存,占一行
else
params.add(obj);
return this;
}
public Object getLastParams() {
return params.isEmpty() ? null : params.getLast();
}
public List<Object> params() {
return params;
}
public Object getOperatingObject() {
return obj;
}
public Pojo setOperatingObject(Object obj) {
this.obj = obj;
return this;
}
public Pojo clear() {
this.params.clear();
return this;
}
public Pojo append(PItem... itemAry) {
if (null != itemAry)
for (PItem item : itemAry) {
if (null != item) {
items.add(item);
item.setPojo(this);
}
}
return this;
}
public Pojo insertFirst(PItem... itemAry) {
items.addAll(0, Lang.list(itemAry));
for (PItem pi : itemAry)
pi.setPojo(this);
return this;
}
public Pojo setItem(int index, PItem pi) {
items.set(index, pi);
pi.setPojo(this);
return this;
}
public PItem getItem(int index) {
return items.get(index);
}
public Pojo removeItem(int index) {
items.remove(index);
return this;
}
@Override
public NutPojo setSqlType(SqlType sqlType) {
return (NutPojo) super.setSqlType(sqlType);
}
public String toString() {
if (SqlType.RUN == this.getSqlType()) {
return this.getSqlType().name()
+ (null == before ? "" : " :before{...}")
+ (null == after ? "" : " :after{...}");
}
return super.toString();
}
public Pojo duplicate() {
throw Lang.noImplement();
}
private int _params_count() {
if (_pmnum < 0) {
_pmnum = 0;
Entity<?> en = getEntity();
for (PItem item : items) {
_pmnum += item.paramCount(en);
}
}
return _pmnum;
}
}