package com.alibaba.druid.sql.dialect.db2.ast.stmt;

import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLName;
import com.alibaba.druid.sql.ast.expr.SQLListExpr;
import com.alibaba.druid.sql.ast.statement.SQLCreateStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableElement;
import com.alibaba.druid.sql.dialect.db2.ast.DB2SQLObjectImpl;
import com.alibaba.druid.sql.dialect.db2.ast.expr.DB2OptionValue;
import com.alibaba.druid.sql.dialect.db2.ast.expr.constraint.DB2StorageParameter;
import com.alibaba.druid.sql.dialect.db2.visitor.DB2ASTVisitor;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
import java.util.ArrayList;
import java.util.List;

public class DB2CreateTableStatement extends SQLCreateTableStatement implements DB2SQLStatement, SQLCreateStatement {
   private TableType tableType;
   private SQLName ofType;
   private List<SQLExpr> parentTables = new ArrayList();
   private List<DB2StorageParameter> parameters = new ArrayList();
   private OnCommit onCommit;
   private DB2TableDistributedBy distributedBy;
   private Boolean withData;
   private Boolean withNoData;
   private Boolean as;
   private DB2SelectStatement query;
   private Boolean distributeOn = false;
   private Boolean random = false;
   private Boolean hash = false;
   private SQLListExpr hashCols;
   private Boolean organizeOn = false;
   private SQLExpr organizeOnCol;
   private Boolean none = false;
   private Boolean rowSecurity = false;
   private boolean dataVersionRetentionTime;
   private SQLExpr dataVersionRetentionTimeNum;

   public SQLExpr getOrganizeOnCol() {
      return this.organizeOnCol;
   }

   public void setOrganizeOnCol(SQLExpr organizeOnCol) {
      this.organizeOnCol = organizeOnCol;
   }

   public Boolean getWithData() {
      return this.withData;
   }

   public void setWithData(Boolean withData) {
      this.withData = withData;
   }

   public Boolean getWithNoData() {
      return this.withNoData;
   }

   public void setWithNoData(Boolean withNoData) {
      this.withNoData = withNoData;
   }

   public Boolean getAs() {
      return this.as;
   }

   public void setAs(Boolean as) {
      this.as = as;
   }

   public DB2SelectStatement getQuery() {
      return this.query;
   }

   public void setQuery(DB2SelectStatement query) {
      this.query = query;
   }

   public DB2CreateTableStatement() {
      this.dbType = DbType.db2;
   }

   public TableType getTableType() {
      return this.tableType;
   }

   public void setTableType(TableType tableType) {
      this.tableType = tableType;
   }

   public List<SQLExpr> getParentTables() {
      return this.parentTables;
   }

   public void addParentTable(SQLExpr parentTable) {
      parentTable.setParent(this);
      this.parentTables.add(parentTable);
   }

   public void setParentTables(List<SQLExpr> parentTables) {
      this.parentTables = parentTables;
   }

   public void addStorageParameter(DB2StorageParameter parameter) {
      parameter.setParent(this);
      this.parameters.add(parameter);
   }

   public List<DB2StorageParameter> getParameters() {
      return this.parameters;
   }

   public void setParameters(List<DB2StorageParameter> parameters) {
      this.parameters = parameters;
   }

   public OnCommit getOnCommit() {
      return this.onCommit;
   }

   public void setOnCommit(OnCommit onCommit) {
      this.onCommit = onCommit;
   }

   public DB2TableDistributedBy getDistributedBy() {
      return this.distributedBy;
   }

   public void setDistributedBy(DB2TableDistributedBy distributedBy) {
      this.distributedBy = distributedBy;
      distributedBy.setParent(this);
   }

   public SQLName getOfType() {
      return this.ofType;
   }

   public void setOfType(SQLName ofType) {
      this.ofType = ofType;
      ofType.setParent(this);
   }

   protected void accept0(SQLASTVisitor visitor) {
      this.accept0((DB2ASTVisitor)visitor);
   }

   public void accept0(DB2ASTVisitor v) {
      if (v.visit(this)) {
         this.acceptChild(v, this.tableSource);
         this.acceptChild(v, this.ofType);
         this.acceptChild(v, this.tableElementList);
         this.acceptChild(v, this.parentTables);
         this.acceptChild(v, this.parameters);
         this.acceptChild(v, this.tablespace);
         this.acceptChild(v, this.distributedBy);
         this.acceptChild(v, this.partitionColumns);
      }

      v.endVisit(this);
   }

   public DB2CreateTableStatement clone() {
      DB2CreateTableStatement c = new DB2CreateTableStatement();
      c.setTableType(this.tableType);
      c.setIfNotExiists(this.ifNotExists);
      c.setTableSource(this.tableSource.clone());
      if (this.ofType != null) {
         c.setOfType(this.ofType);
      }

      for(SQLTableElement sqlTableElement : c.tableElementList) {
         SQLTableElement col = sqlTableElement.clone();
         col.setParent(c);
         c.tableElementList.add(col);
      }

      for(SQLExpr parentTable : this.parentTables) {
         c.addParentTable(parentTable.clone());
      }

      for(DB2StorageParameter parameter : this.parameters) {
         this.addStorageParameter(parameter.clone());
      }

      if (this.tablespace != null) {
         c.setTablespace(this.tablespace.clone());
      }

      if (this.distributedBy != null) {
         c.setDistributedBy(this.distributedBy.clone());
      }

      c.onCommit = this.onCommit;
      return c;
   }

   public Boolean getDistributeOn() {
      return this.distributeOn;
   }

   public void setDistributeOn(Boolean distributeOn) {
      this.distributeOn = distributeOn;
   }

   public Boolean getRandom() {
      return this.random;
   }

   public void setRandom(Boolean random) {
      this.random = random;
   }

   public Boolean getHash() {
      return this.hash;
   }

   public void setHash(Boolean hash) {
      this.hash = hash;
   }

   public SQLListExpr getHashCols() {
      return this.hashCols;
   }

   public void setHashCols(SQLListExpr hashCols) {
      this.hashCols = hashCols;
   }

   public Boolean getOrganizeOn() {
      return this.organizeOn;
   }

   public void setOrganizeOn(Boolean organizeOn) {
      this.organizeOn = organizeOn;
   }

   public Boolean getNone() {
      return this.none;
   }

   public void setNone(Boolean none) {
      this.none = none;
   }

   public Boolean getRowSecurity() {
      return this.rowSecurity;
   }

   public void setRowSecurity(Boolean rowSecurity) {
      this.rowSecurity = rowSecurity;
   }

   public boolean isDataVersionRetentionTime() {
      return this.dataVersionRetentionTime;
   }

   public void setDataVersionRetentionTime(boolean dataVersionRetentionTime) {
      this.dataVersionRetentionTime = dataVersionRetentionTime;
   }

   public SQLExpr getDataVersionRetentionTimeNum() {
      return this.dataVersionRetentionTimeNum;
   }

   public void setDataVersionRetentionTimeNum(SQLExpr dataVersionRetentionTimeNum) {
      this.dataVersionRetentionTimeNum = dataVersionRetentionTimeNum;
   }

   public static enum TableType {
      TEMPORARY,
      TEMP,
      GLOBAL_TEMPORARY,
      GLOBAL_TEMP,
      LOCAL_TEMPORARY,
      LOCAL_TEMP,
      GLOBAL_UNLOGGED,
      LOCAL_UNLOGGED,
      UNLOGGED;
   }

   public static enum OnCommit {
      preserveRows,
      deleteRows,
      drop;
   }

   public static class DB2TableDistributedBy extends DB2SQLObjectImpl {
      private List<DB2OptionValue> columns = new ArrayList();
      private Option option;

      public void addColum(DB2OptionValue column) {
         this.columns.add(column);
         column.setParent(this);
      }

      public List<DB2OptionValue> getColumns() {
         return this.columns;
      }

      public void setColumns(List<DB2OptionValue> columns) {
         this.columns = columns;
      }

      public Option getOption() {
         return this.option;
      }

      public void setOption(Option option) {
         this.option = option;
      }

      public void accept0(SQLASTVisitor visitor) {
         this.accept0((DB2ASTVisitor)visitor);
      }

      public void accept0(DB2ASTVisitor visitor) {
         if (visitor.visit(this)) {
            this.acceptChild(visitor, this.columns);
         }

         visitor.endVisit(this);
      }

      public DB2TableDistributedBy clone() {
         DB2TableDistributedBy c = new DB2TableDistributedBy();

         for(DB2OptionValue column : this.columns) {
            c.addColum(column.clone());
         }

         c.option = this.option;
         return c;
      }

      public static enum Option {
         by,
         randomly,
         replicated;
      }
   }
}
