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 CacheDB2 extends CacheData {
   public CacheDB2(DataBase dataBase, CountDownLatch cdl) {
      super(dataBase, cdl);
   }

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

      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("db2结束缓存");
      }

   }

   public List<Schema> cacheToMemory() throws SQLException {
      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().trim();
         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 TRIM(t.SCHEMANAME) AS SCHEMANAME  from syscat.schemata t WHERE t.DEFINERTYPE  = 'U'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Schema schema = new Schema(resultSet.getString("SCHEMANAME"));
         schema.setRealName(resultSet.getString("SCHEMANAME"));
         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 NAME from sysibm.systables where type='T' and creator='" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         Table table = new Table(resultSet.getString("NAME"), schema);
         table.setRealName(resultSet.getString("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 COLNAME,TYPENAME from syscat.columns where tabname='" + table + "' and tabschema='" + schema + "'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         columns.add(new Column(resultSet.getString("COLNAME"), schema, table, resultSet.getString("TYPENAME")));
      }

      resultSet.close();
      return columns;
   }

   public List<View> getView(Statement statement, String schema) throws SQLException {
      List<View> views = new ArrayList();
      String sql = "SELECT VIEWNAME ,TEXT from syscat.views WHERE OWNER = 'DB2USER'";
      ResultSet resultSet = statement.executeQuery(sql);

      while(resultSet.next()) {
         String table_name = resultSet.getString("VIEWNAME");
         String view_definition = resultSet.getString("TEXT").replaceAll("`", "");
         views.add(new View(table_name, view_definition));
      }

      resultSet.close();
      return views;
   }
}
