package util.getdata;

import bean.Column;
import bean.DataBase;
import bean.Schema;
import bean.Table;
import bean.View;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import util.JdbcCacheUtil;

public class CacheGreenPlum extends CacheData {
   public CacheGreenPlum(DataBase dataBase, CountDownLatch cdl) {
      super(dataBase, cdl);
   }

   public void run() {
      System.out.println("GreenPlum开始缓存");

      try {
         this.cacheWriteToRedis();
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            JdbcCacheUtil.closeConnection(this.connection);
            if (this.statement != null) {
               this.statement.close();
            }
         } catch (SQLException throwables) {
            throwables.printStackTrace();
         }

         this.getCdl().countDown();
         System.out.println("GreenPlum结束缓存");
      }

   }

   public List<Schema> cacheToMemory() throws SQLException, ClassNotFoundException {
      try {
         Class.forName("org.postgresql.Driver");
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      }

      this.connection = JdbcCacheUtil.getConnection(this.DataBase.getUrl(), this.DataBase.getUsername(), this.DataBase.getPassword());
      this.statement = this.connection.createStatement();
      List<Schema> schemaList = this.getSchema(this.statement);

      for(Schema schema : schemaList) {
         String schemaName = schema.getRealName();
         if (!this.DataBase.getExcludeSchema().contains(schemaName)) {
            List<Table> tableList = this.getTable(this.statement, schemaName);
            schema.setTableList(tableList);

            for(Table table : tableList) {
               List<Column> columnList = this.getColumn(this.statement, schemaName, table.getRealName());
               table.setColumnList(columnList);
            }

            List<View> viewList = this.getView(this.statement, schemaName);
            schema.setViewList(viewList);
            schema.setSynonymList(new ArrayList());
         }
      }

      return schemaList;
   }

   public List<Schema> getSchema(Statement statement) throws SQLException {
      List<Schema> schemas = new ArrayList();
      String sql = "select SCHEMA_NAME from information_schema.schemata";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Schema schema = new Schema(resultSet.getString("SCHEMA_NAME"));
         schema.setRealName(resultSet.getString("SCHEMA_NAME"));
         schemas.add(schema);
      }

      resultSet.close();
      return schemas;
   }

   public List<Table> getTable(Statement statement, String schema) throws SQLException {
      List<Table> tables = new ArrayList();
      String sql = "select TABLE_NAME from information_schema.tables where TABLE_TYPE = 'BASE TABLE' AND table_schema='" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Table table = new Table(resultSet.getString("TABLE_NAME"), schema);
         table.setRealName(resultSet.getString("TABLE_NAME"));
         tables.add(table);
      }

      resultSet.close();
      return tables;
   }

   public List<Column> getColumn(Statement statement, String schema, String table) throws SQLException {
      List<Column> columns = new ArrayList();
      String sql = "select COLUMN_NAME,DATA_TYPE,case  \n                when data_type = 'longtext' or data_type = 'datetime' or data_type = 'clob' or data_type = 'date' or data_type = 'time' or data_type = 'timestamp' then '' \n                when CHARACTER_MAXIMUM_LENGTH is not null then ''||CHARACTER_MAXIMUM_LENGTH \n                when (NUMERIC_PRECISION is not null and numeric_scale is not null and numeric_scale=0)then ''||NUMERIC_PRECISION \n                when (NUMERIC_PRECISION is not null and numeric_scale is not null)then ''||NUMERIC_PRECISION||','||numeric_scale \n                when (NUMERIC_PRECISION is not null)then ''||NUMERIC_PRECISION \n                end as COLUMN_LENGTH  from information_schema.columns where TABLE_SCHEMA = '" + schema + "' and TABLE_NAME = '" + table + "' order by table_schema ,table_name,ordinal_position ";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Column column = new Column(resultSet.getString("COLUMN_NAME"), schema, table, resultSet.getString("DATA_TYPE"));
         column.setColumnType(column.getDataType());
         column.setLength(resultSet.getString("COLUMN_LENGTH"));
         columns.add(column);
      }

      resultSet.close();
      return columns;
   }

   public List<View> getView(Statement statement, String schema) throws SQLException {
      List<View> views = new ArrayList();
      String sql = "select TABLE_NAME,VIEW_DEFINITION from information_schema.VIEWS where TABLE_SCHEMA = '" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         String table_name = resultSet.getString("TABLE_NAME");
         String view_definition = resultSet.getString("VIEW_DEFINITION").replaceAll("(?i)[():]|text", "");
         views.add(new View(table_name, view_definition));
      }

      resultSet.close();
      return views;
   }
}
