package cn.edu.whu.boot.common.utils.xml;

import cn.edu.whu.boot.common.domain.CommonConstant;
import cn.edu.whu.boot.common.domain.SqlStringConstant;
import cn.edu.whu.boot.common.utils.collection.DbTypeMappingUtil;
import cn.edu.whu.boot.common.utils.collection.PostgreSqlUtil;
import cn.edu.whu.boot.common.utils.collection.ShapeTypeUtil;
import cn.edu.whu.boot.common.utils.collection.TableOperationUtil;
import cn.edu.whu.boot.xml.domain.Task;
import cn.edu.whu.boot.xml.xmlreader.bean.Config;
import cn.edu.whu.boot.xml.xmlreader.bean.Field;
import cn.edu.whu.boot.xml.xmlreader.bean.Table;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * SQL 的拼接工具类!
 *
 * 在看下面的代码前，先了解本系统中的一些基础概念!!!
 * 根表：根表指的是带有地理位置的表，也就是说具有空间字段，大多数我们都是基于根表采集数据。
 *       任务中也可以有多个根表!
 * 多媒体表：每个根表都会有一个对应的多媒体表，用于存储对应的多媒体信息!
 * 根表历史表、多媒体历史表：因此涉及到数据多次采集、审核的问题，因此会出现数据具有多个版本，旧版本的数据放在历史表中
 * 非根表：就是普通的表，没有空间字段
 * 轨迹表：每个任务有且只有一个轨迹表
 * 草图表：每个任务有且只有一个草图表
 */
public class GenerateSqlUtil{

    /**
     * 根据任务构建 Schema 创建的 SQL
     */
    public static String generateSchemaCreateSql(Task task){
        String databaseName = task.getDatabaseName();
        String schemaName = PostgreSqlUtil.transformString(databaseName);
        return MessageFormat.format(SqlStringConstant.DROP_SCHEMA, schemaName) +
                MessageFormat.format(SqlStringConstant.CREATE_SCHEMA, schemaName);
    }

    /**
     * 根据任务构建数据库表创建的 SQL
     * @param task          Task 对象
     * @param isHistory     如果为 true，表明需要创建历史数据表，历史数据表带有 _history 后缀
     */
    public static String generateDatabaseTableSql(Task task, boolean isHistory){
        JSONObject configJsonObject = JSON.parseObject(task.getConfig());
        Config config = JSON.toJavaObject(configJsonObject, Config.class);

        // 拼接删除创建 schema 的 sql
        String databaseName = task.getDatabaseName();
        StringBuilder sqlStringBuilder = new StringBuilder();

        for(Map.Entry<String, Table> entry : config.getTables().entrySet()){
            StringBuilder createTableSqlStringBuilder = new StringBuilder();
            StringBuilder commentStringBuilder = new StringBuilder();
            // 定义该 boolean 类型属性，用于判断前端传入的数据是否数据类型都给出
            boolean isCompleted = true;
            // 后面定义联合主键时需要
            String primaryKey = null;
            String tableKey = entry.getKey();
            Table table = entry.getValue();

            // 拼接创建 table 的 sql

            // postgreSqltableName 表示数据库中的表名
            String postgreSqltableName = PostgreSqlUtil.buildTableNameString(databaseName, tableKey,
                                                                             false, isHistory);
            createTableSqlStringBuilder.append(MessageFormat.format(SqlStringConstant.DROP_TABLE, postgreSqltableName))
                    .append(MessageFormat.format(SqlStringConstant.CREATE_TABLE_PREFIX, postgreSqltableName));
            // table.getName() 不为空的话，表示数据库中表注释
            if(table.getName() != null){
                commentStringBuilder.append(MessageFormat.format(SqlStringConstant.CREATE_TABLE_COMMENT,
                                                                 postgreSqltableName,
                                                                 "\'" + table.getName() + "\'"));
            }

            // 拼接创建 field 的 sql
            for(Map.Entry<String, Field> fieldEntry : table.getFields().entrySet()){
                Field field = fieldEntry.getValue();
                String controlType = field.getType();

                // 剔除 camera、divider 控件类型字段 & 有关联字段的
                if ((controlType != null &&
                        (CommonConstant.CAMERA.equals(controlType) || "divider".equals(controlType)))
                        || field.getAssociate() != null
                        || field.getCollection() != null) {
                    continue;
                }

                // 只处理有dbtype的field
                String dbType = field.getDbType();
                if (dbType == null || dbType.isEmpty()) {
                    continue;
                }

                String postgreSqlDataType = DbTypeMappingUtil.changeDataType(dbType.toLowerCase());
                String fieldKey = field.getKey();

                if (field.isIdentity()) {
                    // 如果主键自增，根据主键的数据类型拼接
                    primaryKey = PostgreSqlUtil.transformString(fieldKey);
                    switch(dbType.toLowerCase()){
                        case CommonConstant.INTEGER:
                            createTableSqlStringBuilder.append(primaryKey).append(" serial,");
                            break;
                        case CommonConstant.LONG:
                            createTableSqlStringBuilder.append(primaryKey).append(" bigserial,");
                            break;
                        default:
                    }
                } else {
                    if(postgreSqlDataType != null){
                        createTableSqlStringBuilder.append(PostgreSqlUtil.transformString(fieldKey)).append(" ")
                                .append(postgreSqlDataType).append(",");
                    }
                }

                // 添加字段注释
                if(field.getName() != null){
                    commentStringBuilder.append(MessageFormat.format(SqlStringConstant.CREATE_COLUMN_COMMENT,
                            PostgreSqlUtil.buildColumnNameString(databaseName, tableKey, fieldKey),
                            "\'" + field.getName() + "\'"));
                }
            }

            // 所有表都加版本号字段，如果 isHistory == true，需要设置联合主键
            if(primaryKey != null){
                if(isHistory){
                    createTableSqlStringBuilder.append(MessageFormat.format(SqlStringConstant.CREATE_UNION_PRIMARY_KEY,
                                                                            primaryKey, CommonConstant.FIX_FIELD_VERSION));
                }
                else{
                    createTableSqlStringBuilder.append(MessageFormat.format(SqlStringConstant.CREATE_PRIMARY_KEY,
                                                                            primaryKey));
                }
            }
            sqlStringBuilder.append(createTableSqlStringBuilder.toString())
                    .append(commentStringBuilder.toString());
        }
        return sqlStringBuilder.toString();
    }

    /**
     * 根据任务构建空间表对应的多媒体表创建 SQL
     *
     * @param task                  Task 对象
     * @param geometryTableKeyList  空间表名集合
     * @param isHistory             如果为 true，表明需要创建历史数据表，历史数据表带有 _history 后缀
     */
    public static String generateMultiMediaSql(Task task, boolean isHistory, List<String> geometryTableKeyList){
        StringBuilder sqlStringBuilder = new StringBuilder();
        for(String tableKey : geometryTableKeyList){
            String postgresqlTableKey = PostgreSqlUtil.buildTableNameString(task.getDatabaseName(), tableKey,
                                                                            true, isHistory);
            sqlStringBuilder.append(MessageFormat.format(SqlStringConstant.CREATE_MEDIA_TABLE_SQL,
                                                         postgresqlTableKey));
            if(isHistory){
                sqlStringBuilder.append(SqlStringConstant.CREATE_MEDIA_UNION_PRIMARY_KEY);
            }
            else{
                sqlStringBuilder.append(SqlStringConstant.CREATE_MEDIA_PRIMARY_KEY);
            }
        }
        return sqlStringBuilder.toString();
    }

    /**
     * 生成任务固定的 route_line 和 draft 表的创建 SQL
     */
    public static String generateRouteAndDraftSql(Task task){
        String databaseName = task.getDatabaseName();
        String route = PostgreSqlUtil.buildTableNameString(databaseName, CommonConstant.ROUTE_LINE,
                                                           false, false);
        String draft = PostgreSqlUtil.buildTableNameString(databaseName, CommonConstant.DRAFT,
                                                           false, false);
        return MessageFormat.format(SqlStringConstant.CREATE_ROUTE_TABLE_SQL, route) +
                MessageFormat.format(SqlStringConstant.CREATE_DRAFT_TABLE_SQL, draft);
    }

    /**
     * 基于 String databaseName, Table table, Integer taskId, Integer userId 构建
     * 向根表插入记录的 Insert Sql 语句!  注意该方法针对根表
     */
    public static String generateInsertSql(String databaseName, Table table, Integer taskId, Integer userId){
        StringBuilder insertSqlStringBuilder = new StringBuilder();
        insertSqlStringBuilder.append("INSERT INTO ");
        StringBuilder valuesStringBuilder = new StringBuilder();
        valuesStringBuilder.append("VALUES (");
        String tableName = PostgreSqlUtil.buildTableNameString(databaseName, table.getKey(),
                                                               false, false);
        insertSqlStringBuilder.append(tableName).append(" (");
        for(Map.Entry<String, Field> entry : table.getFields().entrySet()){
            String fieldKey = entry.getKey();
            Field field = entry.getValue();
            Object fieldValue = field.getValue();
            String fieldDbType = field.getDbType();
            String fieldType = field.getType();
            // 注意拼接时候除去特殊的 Field
            if(fieldValue == null || fieldDbType == null
                    || (fieldType != null && CommonConstant.CAMERA.equals(fieldType))
                    || field.isIdentity() || field.getAssociate() != null
                    || field.getCollection() != null
                    || fieldKey.equals(CommonConstant.FIX_FIELD_REASON)){
                continue;
            }
            insertSqlStringBuilder.append(PostgreSqlUtil.transformString(fieldKey)).append(",");
            String fieldAutoDate = field.getAutoDate();
            if(fieldAutoDate != null && !"".equals(fieldAutoDate)){
                if(fieldDbType.equals(CommonConstant.DATE)){
                    valuesStringBuilder.append(generatePostgreSqlDateValue(fieldValue, fieldAutoDate)).append(",");
                }
                else{
                    valuesStringBuilder.append("\'").append(fieldValue).append("\',");
                }
                continue;
            }

            if(fieldKey.equals(CommonConstant.FIX_FIELD_STATUS)){
                valuesStringBuilder.append(1).append(",");
                continue;
            }
            if(field.isGeometry()){
                // 若Field是Geometry，将前端传来ArcGISShapeString变成标准GeoJson格式的FeatureString
                byte[] result = Base64.getDecoder().decode(field.getValue().toString());
                valuesStringBuilder.append("\'").append(ShapeTypeUtil.changeArcGISToGeometry(new String(result))).append("\',");
                continue;
            }
            if(fieldType != null && fieldType.equals(CommonConstant.PHOTO) &&  !"".equals(fieldValue)){
                valuesStringBuilder.append("\'").append(MessageFormat.format(CommonConstant.MEDIA_FILE_PATHNAME,
                                                                             taskId, userId, field.getValue()))
                        .append("\',");
                continue;
            }
            valuesStringBuilder = appendValueForDifferentField(valuesStringBuilder, fieldValue, fieldDbType,
                                                               CommonConstant.DATE_FORMAT_STRING);
        }

        // 另外需要添加 create_time 、update_time 内容字段
        insertSqlStringBuilder.append(CommonConstant.FIX_FIELD_CREATE_TIME).append(",").
                append(CommonConstant.FIX_FIELD_UPDATE_TIME).append(",");
        valuesStringBuilder.append(generatePostgreSqlDateValue(new Date(), CommonConstant.DATE_FORMAT_STRING))
                .append(",").append(generatePostgreSqlDateValue(new Date(), CommonConstant.DATE_FORMAT_STRING))
                .append(",");

        return insertSqlStringBuilder.substring(0, insertSqlStringBuilder.length() - 1) + ") "
                + valuesStringBuilder.substring(0, valuesStringBuilder.length() - 1) + ");";
    }

    /**
     * 根据databaseName、tableName、fieldsMap、父表插入记录的polygonId 和versionCode生成insertSql语句 （针对子表）
     */
    public static String generateInsertSql(String databaseName, String tableName, Map<String, Field> fieldsMap, Long polygonId, int version){
        StringBuilder insertSqlStringBuilder = new StringBuilder();
        insertSqlStringBuilder.append("INSERT INTO ");
        StringBuilder valuesStringBuilder = new StringBuilder();
        valuesStringBuilder.append("VALUES (");
        insertSqlStringBuilder.append(PostgreSqlUtil.buildTableNameString(databaseName, tableName, false, false)).append(" (");
        Set<String> fieldsKeySet = fieldsMap.keySet();
        // 注意拼接时候除去 Type 为 camera 的 Field
        for(String fieldKey : fieldsKeySet){
            Field field = fieldsMap.get(fieldKey);
            if(field.isParentID()){
                field.setValue(polygonId);
            }
            if(field.getValue() == null || field.getDbType() == null || (field.getType() != null && field.getType().equals("camera")) || field.isIdentity() || field.getAssociate() != null || field.getCollection() != null){
                continue;
            }
            insertSqlStringBuilder.append(PostgreSqlUtil.transformString(field.getKey())).append(",");
            if(field.getAutoDate() != null && !field.getAutoDate().equals("")){
                valuesStringBuilder.append(generatePostgreSqlDateValue(field.getValue(), field.getAutoDate())).append(",");
                continue;
            }
            switch(field.getDbType().toLowerCase()){
                case "integer":
                    try {
                        int intVal = Integer.parseInt(field.getValue().toString());
                        valuesStringBuilder.append(Math.abs(intVal)).append(",");
                    } catch (Exception e) {
                        throw new RuntimeException("字段 " + field.getKey() + " 不是合法的整数: " + field.getValue(), e);
                    }
//                    if (field.getParentID()) {
//                        System.out.println("处理父ID字段: " + field.getKey());
//                        valuesStringBuilder.append("'").append(polygonId).append("',");
//                    }
//                    else{
//                        int intVal = Integer.parseInt(field.getValue().toString());
//                        valuesStringBuilder.append(Math.abs(intVal)).append(",");
//                    }
                    break;
                case "double":
//                    valuesStringBuilder.append(polygonId).append(",");
                    // 这里应该用字段自己的值，不是 polygonId
                    valuesStringBuilder.append(field.getValue()).append(",");
                    break;
                case "date":
                    valuesStringBuilder.append(generatePostgreSqlDateValue(field.getValue(), CommonConstant.DATE_FORMAT_STRING)).append(",");
                    break;
                default:
                    // 👇 加入几何字段的解码处理
                    if (field.isGeometry()) {
                        try {
                            byte[] decoded = Base64.getDecoder().decode(field.getValue().toString());
//                            String geojson = ShapeTypeUtil.changeArcGISToGeometry(new String(decoded, StandardCharsets.UTF_8));
//                            valuesStringBuilder.append("'").append(geojson).append("',");
                            valuesStringBuilder.append("\'").append(ShapeTypeUtil.changeArcGISToGeometry(new String(decoded))).append("\',");
                        } catch (Exception e) {
                            throw new RuntimeException("几何字段解析失败: " + field.getKey(), e);
                        }
                    }
//                    else if (field.isParentID()) {
//                        System.out.println("处理父ID字段: " + field.getKey());
//                        valuesStringBuilder.append("'").append(polygonId).append("',");
//                    }
                    else {
                        valuesStringBuilder.append("'").append(field.getValue()).append("',");
                    }
                    break;
            }
        }
        insertSqlStringBuilder.append(CommonConstant.FIX_FIELD_VERSION).append(",");
        valuesStringBuilder.append(version).append(",");
//        // 去除最后的逗号，并组合最终 SQL
//        String finalSql = insertSqlStringBuilder.substring(0, insertSqlStringBuilder.length() - 1) +
//                ") " +
//                valuesStringBuilder.substring(0, valuesStringBuilder.length() - 1) +
//                ");";
//
//        //  打印最终 SQL
//        System.out.println(">>> 最终生成 SQL: " + finalSql);
        return insertSqlStringBuilder.substring(0, insertSqlStringBuilder.length() - 1) + ") " + valuesStringBuilder.substring(0, valuesStringBuilder.length() - 1) + ");";
    }

    /**
     * 根据data、databaseName、tableName、configString生成insertSql语句 （针对历史表）
     */
    public static String generateInsertSqlByAllFields(Map<String, Object> data, String databaseName, String tableName, String configString){
        String trueDatabaseTableName = PostgreSqlUtil.buildTableNameString(databaseName, tableName, false, false);
        StringBuilder insertStringBuilder = new StringBuilder();
        StringBuilder valueStringBuilder = new StringBuilder();
        insertStringBuilder.append("insert into ").append(trueDatabaseTableName).append("(");
        valueStringBuilder.append(" values(");
        JSONObject configJsonObject = JSON.parseObject(configString);
        Config config = JSON.toJavaObject(configJsonObject, Config.class);
        Map<String, Table> tables = config.getTables();
        Table table;
        if(tableName.endsWith(CommonConstant.HISTORY_SUFFIX)){
            table = tables.get(tableName.substring(0, tableName.length() - CommonConstant.HISTORY_SUFFIX.length()));
        }
        else{
            table = tables.get(tableName);
        }
        Map<String, Field> fields = table.getFields();
        for(Map.Entry<String, Object> entry : data.entrySet()){
            insertStringBuilder.append(PostgreSqlUtil.transformString(entry.getKey())).append(",");
            Field field = fields.get(entry.getKey());
            if(field.getAutoDate() != null && !field.getAutoDate().equals("") && field.getDbType().equals(CommonConstant.DATE)){
                valueStringBuilder.append(generatePostgreSqlDateValue(entry.getValue().toString(), CommonConstant.DATE_FORMAT_STRING)).append(",");
                continue;
            }
            valueStringBuilder = appendValueForDifferentField(valueStringBuilder, entry.getValue(), field.getDbType().toLowerCase(), null);
        }
        return insertStringBuilder.substring(0, insertStringBuilder.length() - 1) + ") " + valueStringBuilder.substring(0, valueStringBuilder.length() - 1) + ");";
    }

    /**
     * 根据databaseName 、table、、polygonId和versionCode生成updateSql  （针对table拼接updateSql ）
     */
    public static String generateUpdateSql(Task task, int userId, Table table, Long polygonId){
        StringBuilder updateSqlStringBuilder = new StringBuilder();
        updateSqlStringBuilder.append("update ").append(PostgreSqlUtil.buildTableNameString(task.getDatabaseName(), table.getKey(), false, false)).append(" set ");
        Map<String, Field> fieldsMap = table.getFields();
        Set<String> fieldsKeySet = fieldsMap.keySet();
        String primaryKey = null;
        for(String fieldKey : fieldsKeySet){
            if (fieldKey.equals("collector")) {
                continue;
            }

            Field field = fieldsMap.get(fieldKey);
            if(field.getValue() == null){
                continue;
            }
            if(field.isIdentity()){
                primaryKey = field.getKey();
            }
            if(fieldKey.equals(CommonConstant.FIX_FIELD_VERSION)){
                updateSqlStringBuilder.append(PostgreSqlUtil.transformString(field.getKey())).append("=").append((int) field.getValue() + 1).append(",");
                continue;
            }
            if(field.getDbType() == null || (field.getType() != null && field.getType().equals("camera")) || field.isIdentity() || field.getAssociate() != null || field.getCollection() != null){
                continue;
            }
            if(field.isGeometry()){
                byte[] result = Base64.getDecoder().decode(field.getValue().toString());
                updateSqlStringBuilder.append(PostgreSqlUtil.transformString(field.getKey())).append("=").append("\'").append(ShapeTypeUtil.changeArcGISToGeometry(new String(result))).append("\',");
                continue;
            }

            if(field.getAutoDate() != null && !field.getAutoDate().equals("") && field.getDbType().equals(CommonConstant.DATE)){
                updateSqlStringBuilder.append(PostgreSqlUtil.transformString(field.getKey())).append("=").append(generatePostgreSqlDateValue(field.getValue(), field.getAutoDate())).append(",");
                continue;
            }

            if(field.getType() != null && field.getType().equals(CommonConstant.PHOTO) &&  !"".equals(field.getValue())){
                updateSqlStringBuilder.append(PostgreSqlUtil.transformString(field.getKey())).append("=").append("'").append(MessageFormat.format(CommonConstant.MEDIA_FILE_PATHNAME,
                        task.getId(), userId, field.getValue()))
                        .append("',");
                continue;
            }
            appendKeyValueForDifferentField(updateSqlStringBuilder, field.getKey(), field.getValue(), field.getDbType().toLowerCase(), CommonConstant.DATE_FORMAT_STRING);
        }

        // 根表数据的更新，需要更新update_time字段值
        updateSqlStringBuilder.append("update_time=").append(generatePostgreSqlDateValue(new Date(), CommonConstant.DATE_FORMAT_STRING)).append(",");
        return updateSqlStringBuilder.substring(0, updateSqlStringBuilder.length() - 1) + " where " + PostgreSqlUtil.transformString(primaryKey) + "=" + polygonId;
    }

    /**
     * 根据data、databaseName 、tableName、primaryKey、primaryKeyValue和versionCode生成updateSql
     * （针对Map<String, Object> data拼接updateSql ）
     */
    public static String generateUpdateSqlByData(Map<String, Object> data, String databaseName, String tableName, String primaryKey, Long primaryKeyValue, String configString){
        Config config = JSON.toJavaObject(JSON.parseObject(configString), Config.class);
        Table table = config.getTables().get(tableName);
        Map<String, Field> fields = table.getFields();
        StringBuilder resultStringBuilder = new StringBuilder("update ").append(PostgreSqlUtil.buildTableNameString(databaseName, tableName, false, false)).append(" set ");
        for(Map.Entry<String, Object> entry : data.entrySet()){
            String autoDate = null;
            if(fields.get(entry.getKey()).getAutoDate() != null && !fields.get(entry.getKey()).getAutoDate().equals("")){
                autoDate = fields.get(entry.getKey()).getAutoDate();
            }
            try{
                if(!entry.getKey().equals(primaryKey)){
                    resultStringBuilder = appendKeyValueForDifferentField(resultStringBuilder, entry.getKey(), entry.getValue(), fields.get(entry.getKey()).getDbType().toLowerCase(), autoDate);
                }
            } catch(Exception e){
                resultStringBuilder = appendKeyValueForDifferentField(resultStringBuilder, entry.getKey(), entry.getValue(), "String", autoDate);
            }

        }
        resultStringBuilder.delete(resultStringBuilder.length() - 1, resultStringBuilder.length());
        resultStringBuilder.append(" where ").append(PostgreSqlUtil.transformString(primaryKey)).append("=").append(primaryKeyValue).append(";");
        return resultStringBuilder.toString();
    }

    /**
     * 针对不同的Field的DBType，进行不同类型值的追加
     */
    private static StringBuilder appendKeyValueForDifferentField(StringBuilder stringBuilder, Object key, Object value, String fieldDBType, String autoDate){
        switch(fieldDBType){
            case "integer":
            case "double":
                stringBuilder.append(PostgreSqlUtil.transformString(key.toString())).append("=").append(value).append(",");
                break;
            case "date":
                stringBuilder.append(PostgreSqlUtil.transformString(key.toString())).append("=").append(generatePostgreSqlDateValue(value, autoDate)).append(",");
                break;
            default:
                stringBuilder.append(PostgreSqlUtil.transformString(key.toString())).append("=").append("\'").append(value).append("\',");
                break;
        }
        return stringBuilder;
    }

    public static StringBuilder appendValueForDifferentField(StringBuilder stringBuilder, Object value, String fieldDBType, String autoDate){
        switch(fieldDBType){
            case "integer":
            case "long":
            case "double":
                stringBuilder.append(value).append(",");
                break;
            case "date":
                stringBuilder.append(generatePostgreSqlDateValue(value, autoDate)).append(",");
                break;
            default:
                String str = value != null ? String.valueOf(value) : "";
                stringBuilder.append("\'").append(str.replace("'", "''")).append("\',");
                break;
        }
        return stringBuilder;
    }

    /**
     * 根据databaseName 、tableName、fieldName(某字段名)、fieldValue（某字段值）生成selectSql（针对某字段查询）
     */
    public static String generateSelectSqlByField(String databaseName, String tableName, String fieldName, Long fieldValue){
        return "SELECT * FROM " + PostgreSqlUtil.buildTableNameString(databaseName, tableName, false, false) + " where " + PostgreSqlUtil.transformString(fieldName) + "=" + fieldValue + ";";
    }

    /**
     * 根据databaseName 、tableName、fieldName(某字段名)、fieldValue（某字段值）和versionId 生成selectSql
     * （针对某字段和version字段联合查询）
     */
    public static String genSqlByPolygonIdAndVersionId(String databaseName, String tableName, String fieldName, Long fieldValue, int version){
        return "SELECT * FROM " + PostgreSqlUtil.buildTableNameString(databaseName, tableName, false, false) + " where " + PostgreSqlUtil.transformString(fieldName) + "=" + fieldValue + " and version=" + version + ";";
    }

    /**
     * postgresql 数据库直接插入时间型数据，拼接成 to_timestamp('2019-08-09 21:21:21','YYYY-MM-DD HH24:MI:SS') 样式
     */
    public static String generatePostgreSqlDateValue(Object obj, String autoDate){
        SimpleDateFormat dbSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String result = "to_timestamp(\'";
        if("java.lang.String".equals(obj.getClass().getName())){
            if(autoDate != null && !"".equals(autoDate)){
                SimpleDateFormat df = new SimpleDateFormat(autoDate);
                try{
                    result = result + dbSimpleDateFormat.format(df.parse(obj.toString()));
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
            else{
                try{
                    result = result + dbSimpleDateFormat.format(dbSimpleDateFormat.parse(obj.toString()));
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
        else{
            if(autoDate != null && !"".equals(autoDate)){
                SimpleDateFormat df = new SimpleDateFormat(autoDate);
                String dateString = df.format(obj);
                try{
                    result = result + dbSimpleDateFormat.format(df.parse(dateString));
                } catch(Exception e){
                    e.printStackTrace();
                }
            }
            else{
                result = result + dbSimpleDateFormat.format(obj);
            }
        }
        result = result + "\',\'YYYY-MM-DD HH24:MI:SS\')";
        return result;
    }

    /**
     * 根据其中 Table 和 createMD5Code 生成 postgresql数据库中的特定的 自增主键sequence，格式为 模式名.表名_主键名_seq
     */
    public static String generatePrimaryKeySeq(String databaseName, Table table){
        return "\'\"" + databaseName + "\".\"" + table.getKey() + "_" + TableOperationUtil.getPrimaryKey(table) + "_seq\"\'";
    }

    /**
     * 生成deleteSql根据表名(表名是在数据库里的名字)和字段名（字段名是在数据库里的名字）
     */
    public static String genDeleteSql(String tableNameInDB, String fieldNameInDB, Object value){
        return "delete from " + tableNameInDB + " where " + fieldNameInDB + "=" + value + ";";
    }
}
