@Override
  public String createTable(
      String connectionToken,
      int schema,
      String tableName,
      boolean unlogged,
      boolean temporary,
      String fill,
      ArrayList<String> col_list,
      HashMap<Integer, String> commentLog,
      ArrayList<String> col_index)
      throws DatabaseConnectionException, PostgreSQLException {

    ConnectionManager connMgr = new ConnectionManager();
    HttpServletRequest request = this.getThreadLocalRequest();

    String clientIP = ConnectionInfo.remoteAddr(request);
    String userAgent = request.getHeader("User-Agent");

    Tables tables = new Tables(connMgr.getConnection(connectionToken, clientIP, userAgent));

    try {
      return tables.create(
          schema,
          q.addQuote(tableName),
          unlogged,
          temporary,
          fill,
          col_list,
          commentLog,
          col_index);
    } catch (SQLException e) {
      throw new PostgreSQLException(e.getMessage());
    }
  }
  @Override
  public String renameItem(String connectionToken, int item, ITEM_TYPE type, String newName)
      throws IllegalArgumentException, DatabaseConnectionException, PostgreSQLException {
    ConnectionManager connMgr = new ConnectionManager();
    HttpServletRequest request = this.getThreadLocalRequest();

    String clientIP = ConnectionInfo.remoteAddr(request);
    String userAgent = request.getHeader("User-Agent");

    try {
      switch (type) {
        case FOREIGN_TABLE:
          ForeignTables fTables =
              new ForeignTables(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return fTables.rename(item, type, q.addQuote(newName));
        case TABLE:
          Tables tables = new Tables(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return tables.rename(item, type, q.addQuote(newName));
        case VIEW:
        case MATERIALIZED_VIEW:
          Views views = new Views(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return views.rename(item, type, newName);
        default:
          return "";
      }
    } catch (SQLException e) {
      throw new PostgreSQLException(e.getMessage());
    }
  }
  @Override
  public String truncate(String connectionToken, int item, ITEM_TYPE type)
      throws DatabaseConnectionException, PostgreSQLException {
    ConnectionManager connMgr = new ConnectionManager();
    HttpServletRequest request = this.getThreadLocalRequest();

    String clientIP = ConnectionInfo.remoteAddr(request);
    String userAgent = request.getHeader("User-Agent");

    Tables tables = new Tables(connMgr.getConnection(connectionToken, clientIP, userAgent));

    try {
      return tables.truncate(item, type);
    } catch (SQLException e) {
      throw new PostgreSQLException(e.getMessage());
    }
  }
  @Override
  public String dropItem(String connectionToken, int item, ITEM_TYPE type, boolean cascade)
      throws IllegalArgumentException, DatabaseConnectionException, PostgreSQLException {
    ConnectionManager connMgr = new ConnectionManager();
    HttpServletRequest request = this.getThreadLocalRequest();

    String clientIP = ConnectionInfo.remoteAddr(request);
    String userAgent = request.getHeader("User-Agent");

    try {
      switch (type) {
        case FOREIGN_TABLE:
          ForeignTables fTables =
              new ForeignTables(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return fTables.drop(item, cascade);
        case TABLE:
          Tables tables = new Tables(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return tables.drop(item, cascade);
        case VIEW:
        case MATERIALIZED_VIEW:
          boolean isMaterialized = false;

          if (type == ITEM_TYPE.MATERIALIZED_VIEW) isMaterialized = true;

          Views views = new Views(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return views.dropView(item, cascade, isMaterialized);
        case FUNCTION:
          Functions functions =
              new Functions(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return functions.dropFunction(item, cascade);
        case SEQUENCE:
          Sequences sequences =
              new Sequences(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return sequences.drop(item, cascade);
        case TYPE:
          Types types = new Types(connMgr.getConnection(connectionToken, clientIP, userAgent));
          return types.dropType(item, cascade);
        default:
          return "";
      }
    } catch (SQLException e) {
      throw new PostgreSQLException(e.getMessage());
    }
  }
  @Override
  public String getList(String connectionToken, int schema, ITEM_TYPE type)
      throws IllegalArgumentException, DatabaseConnectionException {

    ConnectionManager connMgr = new ConnectionManager();
    HttpServletRequest request = this.getThreadLocalRequest();

    String clientIP = ConnectionInfo.remoteAddr(request);
    String userAgent = request.getHeader("User-Agent");

    switch (type) {
      case TABLE:
        Tables tables = new Tables(connMgr.getConnection(connectionToken, clientIP, userAgent));
        return tables.getList(schema);
      case MATERIALIZED_VIEW:
      case VIEW:
        Views views = new Views(connMgr.getConnection(connectionToken, clientIP, userAgent));
        return views.getList(schema);
      case FOREIGN_TABLE:
        ForeignTables fTables =
            new ForeignTables(connMgr.getConnection(connectionToken, clientIP, userAgent));
        return fTables.getList(schema);
      case FUNCTION:
        Functions funcs =
            new Functions(connMgr.getConnection(connectionToken, clientIP, userAgent));
        return funcs.getList(schema);
      case SEQUENCE:
        Sequences seqs = new Sequences(connMgr.getConnection(connectionToken, clientIP, userAgent));
        return seqs.getList(schema);
      case TYPE:
        Types types = new Types(connMgr.getConnection(connectionToken, clientIP, userAgent));
        return types.getList(schema);
      default:
        return "";
    }
  }