All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.oss.driver.internal.core.metadata.schema.queries.CassandraSchemaRows Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.datastax.oss.driver.internal.core.metadata.schema.queries;

import com.datastax.dse.driver.api.core.metadata.DseNodeProperties;
import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.Version;
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.internal.core.adminrequest.AdminRow;
import com.datastax.oss.driver.internal.core.metadata.schema.parsing.DataTypeClassNameParser;
import com.datastax.oss.driver.internal.core.metadata.schema.parsing.DataTypeCqlNameParser;
import com.datastax.oss.driver.internal.core.metadata.schema.parsing.DataTypeParser;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableListMultimap;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMultimap;
import com.datastax.oss.driver.shaded.guava.common.collect.Multimap;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.jcip.annotations.Immutable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Immutable
public class CassandraSchemaRows implements SchemaRows {

  private final Node node;
  private final DataTypeParser dataTypeParser;
  private final List keyspaces;
  private final List virtualKeyspaces;
  private final Multimap tables;
  private final Multimap virtualTables;
  private final Multimap views;
  private final Multimap types;
  private final Multimap functions;
  private final Multimap aggregates;
  private final Map> columns;
  private final Map> virtualColumns;
  private final Map> indexes;
  private final Map> vertices;
  private final Map> edges;

  private CassandraSchemaRows(
      Node node,
      DataTypeParser dataTypeParser,
      List keyspaces,
      List virtualKeyspaces,
      Multimap tables,
      Multimap virtualTables,
      Multimap views,
      Map> columns,
      Map> virtualColumns,
      Map> indexes,
      Multimap types,
      Multimap functions,
      Multimap aggregates,
      Map> vertices,
      Map> edges) {
    this.node = node;
    this.dataTypeParser = dataTypeParser;
    this.keyspaces = keyspaces;
    this.virtualKeyspaces = virtualKeyspaces;
    this.tables = tables;
    this.virtualTables = virtualTables;
    this.views = views;
    this.columns = columns;
    this.virtualColumns = virtualColumns;
    this.indexes = indexes;
    this.types = types;
    this.functions = functions;
    this.aggregates = aggregates;
    this.vertices = vertices;
    this.edges = edges;
  }

  @NonNull
  @Override
  public Node getNode() {
    return node;
  }

  @Override
  public DataTypeParser dataTypeParser() {
    return dataTypeParser;
  }

  @Override
  public List keyspaces() {
    return keyspaces;
  }

  @Override
  public List virtualKeyspaces() {
    return virtualKeyspaces;
  }

  @Override
  public Multimap tables() {
    return tables;
  }

  @Override
  public Multimap virtualTables() {
    return virtualTables;
  }

  @Override
  public Multimap views() {
    return views;
  }

  @Override
  public Multimap types() {
    return types;
  }

  @Override
  public Multimap functions() {
    return functions;
  }

  @Override
  public Multimap aggregates() {
    return aggregates;
  }

  @Override
  public Map> columns() {
    return columns;
  }

  @Override
  public Map> virtualColumns() {
    return virtualColumns;
  }

  @Override
  public Map> indexes() {
    return indexes;
  }

  @Override
  public Map> vertices() {
    return vertices;
  }

  @Override
  public Map> edges() {
    return edges;
  }

  public static class Builder {
    private static final Logger LOG = LoggerFactory.getLogger(Builder.class);

    private final Node node;
    private final DataTypeParser dataTypeParser;
    private final String tableNameColumn;
    private final KeyspaceFilter keyspaceFilter;
    private final String logPrefix;
    private final ImmutableList.Builder keyspacesBuilder = ImmutableList.builder();
    private final ImmutableList.Builder virtualKeyspacesBuilder = ImmutableList.builder();
    private final ImmutableMultimap.Builder tablesBuilder =
        ImmutableListMultimap.builder();
    private final ImmutableMultimap.Builder virtualTablesBuilder =
        ImmutableListMultimap.builder();
    private final ImmutableMultimap.Builder viewsBuilder =
        ImmutableListMultimap.builder();
    private final ImmutableMultimap.Builder typesBuilder =
        ImmutableListMultimap.builder();
    private final ImmutableMultimap.Builder functionsBuilder =
        ImmutableListMultimap.builder();
    private final ImmutableMultimap.Builder aggregatesBuilder =
        ImmutableListMultimap.builder();
    private final Map>
        columnsBuilders = new LinkedHashMap<>();
    private final Map>
        virtualColumnsBuilders = new LinkedHashMap<>();
    private final Map>
        indexesBuilders = new LinkedHashMap<>();
    private final Map>
        verticesBuilders = new LinkedHashMap<>();
    private final Map>
        edgesBuilders = new LinkedHashMap<>();

    public Builder(Node node, KeyspaceFilter keyspaceFilter, String logPrefix) {
      this.node = node;
      this.keyspaceFilter = keyspaceFilter;
      this.logPrefix = logPrefix;
      if (isCassandraV3OrAbove(node)) {
        this.tableNameColumn = "table_name";
        this.dataTypeParser = new DataTypeCqlNameParser();
      } else {
        this.tableNameColumn = "columnfamily_name";
        this.dataTypeParser = new DataTypeClassNameParser();
      }
    }

    private static boolean isCassandraV3OrAbove(Node node) {
      // We already did those checks in DefaultSchemaQueriesFactory.
      // We could pass along booleans (isCassandraV3, isDse...), but passing the whole Node is
      // better for maintainability, in case we need to do more checks in downstream components in
      // the future.
      Version dseVersion = (Version) node.getExtras().get(DseNodeProperties.DSE_VERSION);
      if (dseVersion != null) {
        dseVersion = dseVersion.nextStable();
        return dseVersion.compareTo(Version.V5_0_0) >= 0;
      } else {
        Version cassandraVersion = node.getCassandraVersion();
        if (cassandraVersion == null) {
          cassandraVersion = Version.V3_0_0;
        } else {
          cassandraVersion = cassandraVersion.nextStable();
        }
        return cassandraVersion.compareTo(Version.V3_0_0) >= 0;
      }
    }

    public Builder withKeyspaces(Iterable rows) {
      for (AdminRow row : rows) {
        put(keyspacesBuilder, row);
      }
      return this;
    }

    public Builder withVirtualKeyspaces(Iterable rows) {
      for (AdminRow row : rows) {
        put(virtualKeyspacesBuilder, row);
      }
      return this;
    }

    public Builder withTables(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspace(row, tablesBuilder);
      }
      return this;
    }

    public Builder withVirtualTables(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspace(row, virtualTablesBuilder);
      }
      return this;
    }

    public Builder withViews(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspace(row, viewsBuilder);
      }
      return this;
    }

    public Builder withTypes(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspace(row, typesBuilder);
      }
      return this;
    }

    public Builder withFunctions(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspace(row, functionsBuilder);
      }
      return this;
    }

    public Builder withAggregates(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspace(row, aggregatesBuilder);
      }
      return this;
    }

    public Builder withColumns(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspaceAndTable(row, columnsBuilders);
      }
      return this;
    }

    public Builder withVirtualColumns(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspaceAndTable(row, virtualColumnsBuilders);
      }
      return this;
    }

    public Builder withIndexes(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspaceAndTable(row, indexesBuilders);
      }
      return this;
    }

    public Builder withVertices(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspaceAndTable(row, verticesBuilders);
      }
      return this;
    }

    public Builder withEdges(Iterable rows) {
      for (AdminRow row : rows) {
        putByKeyspaceAndTable(row, edgesBuilders);
      }
      return this;
    }

    private void put(ImmutableList.Builder builder, AdminRow row) {
      String keyspace = row.getString("keyspace_name");
      if (keyspace == null) {
        LOG.warn("[{}] Skipping system row with missing keyspace name", logPrefix);
      } else if (keyspaceFilter.includes(keyspace)) {
        builder.add(row);
      }
    }

    private void putByKeyspace(
        AdminRow row, ImmutableMultimap.Builder builder) {
      String keyspace = row.getString("keyspace_name");
      if (keyspace == null) {
        LOG.warn("[{}] Skipping system row with missing keyspace name", logPrefix);
      } else if (keyspaceFilter.includes(keyspace)) {
        builder.put(CqlIdentifier.fromInternal(keyspace), row);
      }
    }

    private void putByKeyspaceAndTable(
        AdminRow row,
        Map> builders) {
      String keyspace = row.getString("keyspace_name");
      String table = row.getString(tableNameColumn);
      if (keyspace == null) {
        LOG.warn("[{}] Skipping system row with missing keyspace name", logPrefix);
      } else if (table == null) {
        LOG.warn("[{}] Skipping system row with missing table name", logPrefix);
      } else if (keyspaceFilter.includes(keyspace)) {
        ImmutableMultimap.Builder builder =
            builders.computeIfAbsent(
                CqlIdentifier.fromInternal(keyspace), s -> ImmutableListMultimap.builder());
        builder.put(CqlIdentifier.fromInternal(table), row);
      }
    }

    public CassandraSchemaRows build() {
      return new CassandraSchemaRows(
          node,
          dataTypeParser,
          keyspacesBuilder.build(),
          virtualKeyspacesBuilder.build(),
          tablesBuilder.build(),
          virtualTablesBuilder.build(),
          viewsBuilder.build(),
          build(columnsBuilders),
          build(virtualColumnsBuilders),
          build(indexesBuilders),
          typesBuilder.build(),
          functionsBuilder.build(),
          aggregatesBuilder.build(),
          build(verticesBuilders),
          build(edgesBuilders));
    }

    private static  Map> build(
        Map> builders) {
      ImmutableMap.Builder> builder = ImmutableMap.builder();
      builders
          .entrySet()
          .forEach(
              (entry) -> {
                builder.put(entry.getKey(), entry.getValue().build());
              });
      return builder.build();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy