package com.chenyang.nse.bussiness.entity.db;

import com.chenyang.nse.bussiness.entity.vo.Scope;
import com.chenyang.nse.bussiness.enumeration.EdbType;
import com.chenyang.nse.bussiness.tools.jdbc.JdbcTool;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class ColumnInfo {
   private String primarykey;
   private String foreignkey;
   private String tablecat;
   private String tableschem;
   private String tablename;
   private String columnname;
   private String datatype;
   private String typename;
   private String columnsize;
   private String bufferlength;
   private String decimaldigits;
   private String numprecpadix;
   private String nullable;
   private String remarks;
   private String columndef;
   private String sqldatatype;
   private String sqldatetimesub;
   private String charoctetlength;
   private String ordinalposition;
   private String isnullable;
   private String scopecatlog;
   private String scopeschema;
   private String scopetable;
   private String sourcedatatype;
   private String isautoincrement;
   private String scopeid;
   private List<String> scopeidList;
   private List<Scope> scopes;
   private String sensitiveid;
   private String sensitiveLevel;
   private String columnnamehive;
   private String dataareaName;

   public ColumnInfo() {
   }

   public ColumnInfo(String tablecat, String tableschem, String tablename, String columnname, String datatype, String typename, String columnsize, String bufferlength, String decimaldigits, String numprecpadix, String nullable, String remarks, String columndef, String sqldatatype, String sqldatetimesub, String charoctetlength, String ordinalposition, String isnullable, String scopecatlog, String scopeschema, String scopetable, String sourcedatatype, String isautoincrement) {
      this.tablecat = tablecat;
      this.tableschem = tableschem;
      this.tablename = tablename;
      this.columnname = columnname;
      this.datatype = datatype;
      this.typename = typename;
      this.columnsize = columnsize;
      this.bufferlength = bufferlength;
      this.decimaldigits = decimaldigits;
      this.numprecpadix = numprecpadix;
      this.nullable = nullable;
      this.remarks = remarks;
      this.columndef = columndef;
      this.sqldatatype = sqldatatype;
      this.sqldatetimesub = sqldatetimesub;
      this.charoctetlength = charoctetlength;
      this.ordinalposition = ordinalposition;
      this.isnullable = isnullable;
      this.scopecatlog = scopecatlog;
      this.scopeschema = scopeschema;
      this.scopetable = scopetable;
      this.sourcedatatype = sourcedatatype;
      this.isautoincrement = isautoincrement;
   }

   public ColumnInfo(String tablecat, String tableschem, String tablename, String columnname, String datatype, String typename, String columnsize, String bufferlength, String decimaldigits, String numprecpadix, String nullable, String remarks, String columndef, String sqldatatype, String sqldatetimesub, String charoctetlength, String ordinalposition, String isnullable, String scopecatlog, String scopeschema, String scopetable, String sourcedatatype, String isautoincrement, String scopeid, List<Scope> scopes, String sensitiveid, String sensitiveLevel, String dataareaName) {
      this.tablecat = tablecat;
      this.tableschem = tableschem;
      this.tablename = tablename;
      this.columnname = columnname;
      this.datatype = datatype;
      this.typename = typename;
      this.columnsize = columnsize;
      this.bufferlength = bufferlength;
      this.decimaldigits = decimaldigits;
      this.numprecpadix = numprecpadix;
      this.nullable = nullable;
      this.remarks = remarks;
      this.columndef = columndef;
      this.sqldatatype = sqldatatype;
      this.sqldatetimesub = sqldatetimesub;
      this.charoctetlength = charoctetlength;
      this.ordinalposition = ordinalposition;
      this.isnullable = isnullable;
      this.scopecatlog = scopecatlog;
      this.scopeschema = scopeschema;
      this.scopetable = scopetable;
      this.sourcedatatype = sourcedatatype;
      this.isautoincrement = isautoincrement;
      this.scopeid = scopeid;
      this.scopes = scopes;
      this.sensitiveid = sensitiveid;
      this.sensitiveLevel = sensitiveLevel;
      this.dataareaName = dataareaName;
   }

   public ColumnInfo(List<String> scopeList, List<Scope> scopes, String scopeschema, String tablename, String columnname, String sensitiveid, String sensitiveLevel, String dataareaName) {
      this.scopeidList = scopeList;
      this.scopes = scopes;
      this.scopeschema = scopeschema;
      this.tablename = tablename;
      this.columnname = columnname;
      this.sensitiveid = sensitiveid;
      this.sensitiveLevel = sensitiveLevel;
      this.dataareaName = dataareaName;
   }

   public List<Scope> getScopes() {
      return this.scopes;
   }

   public void setScopes(List<Scope> scopes) {
      this.scopes = scopes;
   }

   public String getSensitiveLevel() {
      return this.sensitiveLevel;
   }

   public void setSensitiveLevel(String sensitiveLevel) {
      this.sensitiveLevel = sensitiveLevel;
   }

   public String getDataareaName() {
      return this.dataareaName;
   }

   public void setDataareaName(String dataareaName) {
      this.dataareaName = dataareaName;
   }

   public String getPrimarykey() {
      return this.primarykey;
   }

   public void setPrimarykey(String primarykey) {
      this.primarykey = primarykey;
   }

   public String getForeignkey() {
      return this.foreignkey;
   }

   public void setForeignkey(String foreignkey) {
      this.foreignkey = foreignkey;
   }

   public String getTablecat() {
      return this.tablecat;
   }

   public void setTablecat(String tablecat) {
      this.tablecat = tablecat;
   }

   public String getTableschem() {
      return this.tableschem;
   }

   public void setTableschem(String tableschem) {
      this.tableschem = tableschem;
   }

   public String getTablename() {
      return this.tablename;
   }

   public void setTablename(String tablename) {
      this.tablename = tablename;
   }

   public String getColumnname() {
      return this.columnname;
   }

   public void setColumnname(String columnname) {
      this.columnname = columnname;
   }

   public String getDatatype() {
      return this.datatype;
   }

   public void setDatatype(String datatype) {
      this.datatype = datatype;
   }

   public String getTypename() {
      return this.typename;
   }

   public void setTypename(String typename) {
      this.typename = typename;
   }

   public String getColumnsize() {
      return this.columnsize;
   }

   public void setColumnsize(String columnsize) {
      this.columnsize = columnsize;
   }

   public String getBufferlength() {
      return this.bufferlength;
   }

   public void setBufferlength(String bufferlength) {
      this.bufferlength = bufferlength;
   }

   public String getDecimaldigits() {
      return this.decimaldigits;
   }

   public void setDecimaldigits(String decimaldigits) {
      this.decimaldigits = decimaldigits;
   }

   public String getNumprecpadix() {
      return this.numprecpadix;
   }

   public void setNumprecpadix(String numprecpadix) {
      this.numprecpadix = numprecpadix;
   }

   public String getNullable() {
      return this.nullable;
   }

   public void setNullable(String nullable) {
      this.nullable = nullable;
   }

   public String getRemarks() {
      return this.remarks;
   }

   public void setRemarks(String remarks) {
      this.remarks = remarks;
   }

   public String getColumndef() {
      return this.columndef;
   }

   public void setColumndef(String columndef) {
      this.columndef = columndef;
   }

   public String getSqldatatype() {
      return this.sqldatatype;
   }

   public void setSqldatatype(String sqldatatype) {
      this.sqldatatype = sqldatatype;
   }

   public String getSqldatetimesub() {
      return this.sqldatetimesub;
   }

   public void setSqldatetimesub(String sqldatetimesub) {
      this.sqldatetimesub = sqldatetimesub;
   }

   public String getCharoctetlength() {
      return this.charoctetlength;
   }

   public void setCharoctetlength(String charoctetlength) {
      this.charoctetlength = charoctetlength;
   }

   public String getOrdinalposition() {
      return this.ordinalposition;
   }

   public void setOrdinalposition(String ordinalposition) {
      this.ordinalposition = ordinalposition;
   }

   public String getIsnullable() {
      return this.isnullable;
   }

   public void setIsnullable(String isnullable) {
      this.isnullable = isnullable;
   }

   public String getScopecatlog() {
      return this.scopecatlog;
   }

   public void setScopecatlog(String scopecatlog) {
      this.scopecatlog = scopecatlog;
   }

   public String getScopeschema() {
      return this.scopeschema;
   }

   public void setScopeschema(String scopeschema) {
      this.scopeschema = scopeschema;
   }

   public String getScopetable() {
      return this.scopetable;
   }

   public void setScopetable(String scopetable) {
      this.scopetable = scopetable;
   }

   public String getSourcedatatype() {
      return this.sourcedatatype;
   }

   public void setSourcedatatype(String sourcedatatype) {
      this.sourcedatatype = sourcedatatype;
   }

   public String getIsautoincrement() {
      return this.isautoincrement;
   }

   public void setIsautoincrement(String isautoincrement) {
      this.isautoincrement = isautoincrement;
   }

   public String getScopeid() {
      return this.scopeid;
   }

   public void setScopeid(String scopeid) {
      this.scopeid = scopeid;
   }

   public String getSensitiveid() {
      return this.sensitiveid;
   }

   public void setSensitiveid(String sensitiveid) {
      this.sensitiveid = sensitiveid;
   }

   public List<String> getScopeidList() {
      return this.scopeidList;
   }

   public void setScopeidList(List<String> scopeidList) {
      this.scopeidList = scopeidList;
   }

   public String toString() {
      return "ColumnInfo [tablecat=" + this.tablecat + ", tableschem=" + this.tableschem + ", tablename=" + this.tablename + ", columnname=" + this.columnname + ", datatype=" + this.datatype + ", typename=" + this.typename + ", columnsize=" + this.columnsize + ", bufferlength=" + this.bufferlength + ", decimaldigits=" + this.decimaldigits + ", numprecpadix=" + this.numprecpadix + ", nullable=" + this.nullable + ", remarks=" + this.remarks + ", columndef=" + this.columndef + ", sqldatatype=" + this.sqldatatype + ", sqldatetimesub=" + this.sqldatetimesub + ", charoctetlength=" + this.charoctetlength + ", ordinalposition=" + this.ordinalposition + ", isnullable=" + this.isnullable + ", scopecatlog=" + this.scopecatlog + ", scopeschema=" + this.scopeschema + ", scopetable=" + this.scopetable + ", sourcedatatype=" + this.sourcedatatype + ", isautoincrement=" + this.isautoincrement + "]";
   }

   public static List<ColumnInfo> getColumnInfoByConnection(Connection conn, String schemaPattern, String tableNamePattern, String columnNamePattern) {
      EdbType dbtype = DbInfo.getEdbTypeByConnection(conn);
      if (dbtype == null || !dbtype.getDbcode().equals(EdbType.MYSQL.getDbcode()) && !dbtype.getDbcode().equals(EdbType.RAPIDSDB.getDbcode())) {
         if (conn.toString().indexOf(EdbType.OCEANBASE.getDbcode().toLowerCase()) >= 0) {
            return getColumnInfoByConnectionForOB(conn, schemaPattern, tableNamePattern);
         } else if (conn.toString().indexOf("gbase") >= 0 && conn.toString().indexOf("kingbase") == -1) {
            return getColumnInfoByConnectionForGbase8s(conn, schemaPattern, tableNamePattern);
         } else {
            List<ColumnInfo> list = null;
            if (null == conn) {
               return list;
            } else {
               list = new ArrayList();
               DatabaseMetaData dbmd = null;
               ResultSet rs = null;

               try {
                  dbmd = conn.getMetaData();
                  List<String> primaryKeyList = new ArrayList();
                  if (dbtype.getDbcode().equals(EdbType.POSTGRESQL.getDbcode()) || dbtype.getDbcode().equals(EdbType.GREENPLUM.getDbcode()) || dbtype.getDbcode().equals(EdbType.GAUSS.getDbcode())) {
                     schemaPattern = schemaPattern.toLowerCase();
                     tableNamePattern = tableNamePattern.toLowerCase();
                  }

                  ColumnInfo temp;
                  for(rs = dbmd.getColumns((String)null, schemaPattern, tableNamePattern, columnNamePattern); rs.next(); list.add(temp)) {
                     String tablecat = rs.getString("TABLE_CAT");
                     String tableschem = rs.getString("TABLE_SCHEM");
                     String tablename = rs.getString("TABLE_NAME");
                     String columnname = rs.getString("COLUMN_NAME");
                     String datatype = rs.getString("DATA_TYPE");
                     String typename = rs.getString("TYPE_NAME");
                     String columnsize = rs.getString("COLUMN_SIZE");
                     String bufferlength = rs.getString("BUFFER_LENGTH");
                     String decimaldigits = rs.getString("DECIMAL_DIGITS");
                     String numprecpadix = rs.getString("NUM_PREC_RADIX");
                     String nullable = rs.getString("NULLABLE");
                     String remarks = rs.getString("REMARKS");
                     String columndef = rs.getString("COLUMN_DEF");
                     String sqldatatype = rs.getString("SQL_DATA_TYPE");
                     String sqldatetimesub = rs.getString("SQL_DATETIME_SUB");
                     String charoctetlength = rs.getString("CHAR_OCTET_LENGTH");
                     String ordinalposition = rs.getString("ORDINAL_POSITION");
                     String isnullable = rs.getString("IS_NULLABLE");
                     String scopecatlog = null;
                     String scopeschema = null;
                     String scopetable = null;
                     String sourcedatatype = null;
                     String isautoincrement = null;
                     temp = new ColumnInfo(tablecat, tableschem, tablename, columnname, datatype, typename, columnsize, bufferlength, decimaldigits, numprecpadix, nullable, remarks, columndef, sqldatatype, sqldatetimesub, charoctetlength, ordinalposition, isnullable, scopecatlog, scopeschema, scopetable, sourcedatatype, isautoincrement);
                     temp.setPrimarykey("0");
                     if (primaryKeyList != null && primaryKeyList.size() > 0 && primaryKeyList.contains(temp.getColumnname())) {
                        temp.setPrimarykey("1");
                     }
                  }
               } catch (SQLException e) {
                  e.printStackTrace();
               } finally {
                  try {
                     if (rs != null) {
                        Statement s = rs.getStatement();
                        rs.close();
                        if (s != null) {
                           s.close();
                        }
                     }
                  } catch (SQLException e) {
                     e.printStackTrace();
                  }

               }

               return list;
            }
         }
      } else {
         return getColumnInfoByConnectionForMySql(conn, schemaPattern, tableNamePattern);
      }
   }

   public static List<ColumnInfo> getColumnInfoByConnectionForMySql(Connection conn, String schemaPattern, String tableNamePattern) {
      List<TypeInfo> typeinfolist = JdbcTool.getTypeInfoListByConnection(conn);
      List<ColumnInfo> list = new ArrayList();
      String sql = "SELECT  TABLE_CATALOG, \tTABLE_SCHEMA, \tTABLE_NAME, \tCOLUMN_NAME, \tDATA_TYPE, \tIS_NULLABLE, \tCHARACTER_MAXIMUM_LENGTH, \tNUMERIC_PRECISION, \tNUMERIC_SCALE, \tCOLUMN_KEY,  COLUMN_COMMENT \tFROM \tINFORMATION_SCHEMA. COLUMNS WHERE \ttable_name = ?  AND table_schema = ? ";
      PreparedStatement ps = null;
      ResultSet rs = null;

      try {
         ps = conn.prepareStatement(sql);
         ps.setString(1, tableNamePattern);
         ps.setString(2, schemaPattern);

         ColumnInfo temp;
         for(rs = ps.executeQuery(); rs.next(); list.add(temp)) {
            String tablecat = rs.getString("TABLE_CATALOG");
            String tableschem = rs.getString("TABLE_SCHEMA");
            String tablename = rs.getString("TABLE_NAME");
            String columnname = rs.getString("COLUMN_NAME");
            String typename = rs.getString("DATA_TYPE");
            String datatype = getDataType(typename, typeinfolist);
            String columnsize = rs.getString("CHARACTER_MAXIMUM_LENGTH");
            if (columnsize == null) {
               columnsize = rs.getString("NUMERIC_PRECISION");
            }

            String bufferlength = null;
            String decimaldigits = rs.getString("NUMERIC_SCALE");
            String numprecpadix = null;
            String nullable = rs.getString("IS_NULLABLE");
            String remarks = rs.getString("COLUMN_COMMENT");
            String columndef = null;
            String sqldatatype = null;
            String sqldatetimesub = null;
            String charoctetlength = null;
            String ordinalposition = null;
            String isnullable = rs.getString("IS_NULLABLE");
            String scopecatlog = null;
            String scopeschema = null;
            String scopetable = null;
            String sourcedatatype = null;
            String isautoincrement = null;
            temp = new ColumnInfo(tablecat, tableschem, tablename, columnname, datatype, typename, columnsize, bufferlength, decimaldigits, numprecpadix, nullable, remarks, columndef, sqldatatype, sqldatetimesub, charoctetlength, ordinalposition, isnullable, scopecatlog, scopeschema, scopetable, sourcedatatype, isautoincrement);
            String key = rs.getString("COLUMN_KEY");
            if (key != null && "PRI".equals(key)) {
               temp.setPrimarykey("1");
            } else {
               temp.setPrimarykey("0");
            }
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         try {
            if (rs != null) {
               rs.close();
            }

            if (ps != null) {
               ps.close();
            }
         } catch (SQLException e) {
            e.printStackTrace();
         }

      }

      return list;
   }

   public static List<ColumnInfo> getColumnInfoByConnectionForOB(Connection conn, String schemaPattern, String tableNamePattern) {
      List<TypeInfo> typeinfolist = JdbcTool.getTypeInfoListByConnection(conn);
      List<ColumnInfo> list = new ArrayList();
      String sql = "SELECT \tut.COLUMN_NAME, \tuc.comments,  ut.DATA_TYPE, ut.DATA_LENGTH\tFROM \tuser_tab_columns  ut inner JOIN user_col_comments uc on ut.TABLE_NAME  = uc.table_name  and ut.COLUMN_NAME = uc.column_name\twhere ut.table_name = ?  order by ut.column_name";
      PreparedStatement ps = null;
      ResultSet rs = null;

      try {
         ps = conn.prepareStatement(sql);
         ps.setString(1, tableNamePattern);

         ColumnInfo temp;
         for(rs = ps.executeQuery(); rs.next(); list.add(temp)) {
            String tablecat = null;
            String tableschem = null;
            String columnname = rs.getString("COLUMN_NAME");
            String typename = rs.getString("DATA_TYPE");
            String datatype = null;
            String columnsize = rs.getString("DATA_LENGTH");
            String bufferlength = null;
            String decimaldigits = null;
            String numprecpadix = null;
            String nullable = null;
            String remarks = rs.getString("COMMENTS");
            String columndef = null;
            String sqldatatype = null;
            String sqldatetimesub = null;
            String charoctetlength = null;
            String ordinalposition = null;
            String isnullable = null;
            String scopecatlog = null;
            String scopeschema = null;
            String scopetable = null;
            String sourcedatatype = null;
            String isautoincrement = null;
            temp = new ColumnInfo(tablecat, tableschem, tableNamePattern, columnname, datatype, typename, columnsize, bufferlength, decimaldigits, numprecpadix, nullable, remarks, columndef, sqldatatype, sqldatetimesub, charoctetlength, ordinalposition, isnullable, scopecatlog, scopeschema, scopetable, sourcedatatype, isautoincrement);
            String key = null;
            if (key != null && "PRI".equals(key)) {
               temp.setPrimarykey("1");
            } else {
               temp.setPrimarykey("0");
            }
         }
      } catch (SQLException e) {
         e.printStackTrace();
      } finally {
         try {
            if (rs != null) {
               rs.close();
            }

            if (ps != null) {
               ps.close();
            }
         } catch (SQLException e) {
            e.printStackTrace();
         }

      }

      return list;
   }

   public static List<ColumnInfo> getColumnInfoByConnectionForGbase8s(Connection conn, String schemaPattern, String tableNamePattern) {
      List<ColumnInfo> list = new ArrayList();
      PreparedStatement ps = null;
      ResultSet rs = null;
      ResultSet rsPri = null;

      try {
         DatabaseMetaData metadata = conn.getMetaData();
         rs = metadata.getColumns(schemaPattern, "", tableNamePattern, "");
         rsPri = metadata.getPrimaryKeys(schemaPattern, (String)null, tableNamePattern);
         List<String> priColList = new ArrayList();

         while(rsPri.next()) {
            priColList.add(rsPri.getString(4));
         }

         ColumnInfo temp;
         for(; rs.next(); list.add(temp)) {
            String tablecat = rs.getString("TABLE_CAT");
            String tableschem = rs.getString("TABLE_SCHEM");
            String tablename = rs.getString("TABLE_NAME");
            String columnname = rs.getString("COLUMN_NAME");
            String typename = rs.getString("TYPE_NAME");
            String datatype = rs.getString("DATA_TYPE");
            String columnsize = rs.getString("CHAR_OCTET_LENGTH");
            if (columnsize == null) {
               columnsize = rs.getString("NUM_PREC_RADIX");
            }

            String bufferlength = null;
            String decimaldigits = rs.getString("DECIMAL_DIGITS");
            String numprecpadix = null;
            String nullable = rs.getString("IS_NULLABLE");
            String remarks = rs.getString("REMARKS");
            String columndef = null;
            String sqldatatype = null;
            String sqldatetimesub = null;
            String charoctetlength = null;
            String ordinalposition = null;
            String isnullable = rs.getString("IS_NULLABLE");
            String scopecatlog = null;
            String scopeschema = null;
            String scopetable = null;
            String sourcedatatype = null;
            String isautoincrement = null;
            temp = new ColumnInfo(tablecat, tableschem, tablename, columnname, datatype, typename, columnsize, bufferlength, decimaldigits, numprecpadix, nullable, remarks, columndef, sqldatatype, sqldatetimesub, charoctetlength, ordinalposition, isnullable, scopecatlog, scopeschema, scopetable, sourcedatatype, isautoincrement);
            if (priColList.contains(columnname)) {
               temp.setPrimarykey("1");
            } else {
               temp.setPrimarykey("0");
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            if (rs != null) {
               rs.close();
            }

            if (ps != null) {
               ps.close();
            }
         } catch (SQLException e) {
            e.printStackTrace();
         }

      }

      return list;
   }

   public static String getDataType(String columntype, List<TypeInfo> typeinfo) {
      String datatype = null;

      for(TypeInfo item : typeinfo) {
         if (item.getTypename().equalsIgnoreCase(columntype)) {
            datatype = item.getDatatype().toString();
            break;
         }
      }

      return datatype;
   }

   public String getColumnnamehive() {
      return this.columnnamehive;
   }

   public void setColumnnamehive(String columnnamehive) {
      this.columnnamehive = columnnamehive;
   }
}
