package com.engine.organization.util;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import weaver.conn.RecordSet;

import java.lang.reflect.Method;
import java.sql.Blob;
import java.sql.Clob;
import java.util.ArrayList;
import java.util.List;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QueryObjUtil<T> {

    /**
     * 查询语句
     */
    private String querySQL;

    /**
     * 要转换成的Bean对象
     */
    private Class<?> cla;
    private T obj;
    @SuppressWarnings("unchecked")
    public List<T> query()  {
        RecordSet rs = new RecordSet();
        List<T> list = null;
        int cols;
        try {
            rs.executeQuery(querySQL);
            cols = rs.getColCounts();
            list = new ArrayList<T>();
            while (rs.next()) {
                // 并实例化成对象
                obj = (T) cla.newInstance();
                for (int j = 1; j <= cols; j++) {
                    String colName = iniStr(rs.getColumnName(j).toLowerCase());
                    try {
                        // 通过getter确定bean属性的数据类型
                        Method met = cla.getMethod("get" + colName);
                        // 取得属性的数据类型
                        Class<?> p = met.getReturnType();
                        // 获取set
                        met = obj.getClass().getMethod("set" + colName, p);
                        // 根据属性的数据类型来判断该用哪种数据类型取值，并将值存入对象属性中
                        if (p == String.class) {
                            met.invoke(obj, rs.getString(j));
                        } else if (p == Long.class || p == long.class) {
                            met.invoke(obj, rs.getInt(j));//rs未封装long
                        } else if (p == Double.class || p == double.class) {
                            met.invoke(obj, rs.getDouble(j));
                        } else if (p == Integer.class || p == int.class) {
                            met.invoke(obj, rs.getInt(j));
                        } else if (p == Blob.class) {
                            met.invoke(obj, rs.getBlobStr(j));
                        } else if (p == Boolean.class || p == boolean.class) {
                            met.invoke(obj, rs.getBoolean(j));
                        }
//                        else if (p == Byte.class || p == byte.class) {
//                            met.invoke(obj, rs.getByte(j));
//                        }
//                        else if (p == Short.class || p == short.class) {
//                            met.invoke(obj, rs.getShort(j));
//                        }
                        else if (p == Object.class) {
                            met.invoke(obj, rs.getString(j)); //未封装obj
                        } else if (p == Float.class || p == float.class) {
                            met.invoke(obj, rs.getFloat(j));
                        } else if (p == java.sql.Date.class) {
                            met.invoke(obj, rs.getDate(j));
                        } else if (p == java.util.Date.class) {
                            met.invoke(obj, rs.getDate(j));
                        } else if (p == Clob.class) {
                            met.invoke(obj, rs.getString(j));
                        }
                    } catch (NoSuchMethodException e) {

                    }
                }
                list.add(obj);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }


    /**
     * 处理set属性方法名，首字母为大写
     * @param old
     * @return
     */
    public String iniStr(String old) {
        return old.substring(0, 1).toUpperCase() + old.substring(1);
    }
}
