mirror of https://github.com/apache/cassandra
266 lines
9.3 KiB
Java
266 lines
9.3 KiB
Java
/*
|
|
* 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 org.apache.cassandra.schema;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
import javax.annotation.Nullable;
|
|
|
|
import org.apache.cassandra.cql3.ColumnIdentifier;
|
|
import org.apache.cassandra.cql3.functions.Function;
|
|
import org.apache.cassandra.cql3.functions.FunctionName;
|
|
import org.apache.cassandra.cql3.functions.UserFunction;
|
|
import org.apache.cassandra.db.ColumnFamilyStore;
|
|
import org.apache.cassandra.db.Keyspace;
|
|
import org.apache.cassandra.db.KeyspaceNotDefinedException;
|
|
import org.apache.cassandra.db.marshal.AbstractType;
|
|
import org.apache.cassandra.dht.IPartitioner;
|
|
import org.apache.cassandra.exceptions.InvalidRequestException;
|
|
import org.apache.cassandra.exceptions.UnknownTableException;
|
|
import org.apache.cassandra.io.sstable.Descriptor;
|
|
import org.apache.cassandra.locator.LocalStrategy;
|
|
import org.apache.cassandra.tcm.ClusterMetadata;
|
|
|
|
public interface SchemaProvider
|
|
{
|
|
Set<String> getKeyspaces();
|
|
int getNumberOfTables();
|
|
|
|
ClusterMetadata submit(SchemaTransformation transformation);
|
|
|
|
default UUID getVersion()
|
|
{
|
|
return ClusterMetadata.current().schema.getVersion();
|
|
}
|
|
|
|
Keyspaces localKeyspaces();
|
|
Keyspaces distributedKeyspaces();
|
|
Keyspaces distributedAndLocalKeyspaces();
|
|
Keyspaces getUserKeyspaces();
|
|
|
|
void registerListener(SchemaChangeListener listener);
|
|
void unregisterListener(SchemaChangeListener listener);
|
|
|
|
SchemaChangeNotifier schemaChangeNotifier();
|
|
|
|
Optional<TableMetadata> getIndexMetadata(String keyspace, String index);
|
|
|
|
default TableMetadata getTableMetadata(Descriptor descriptor)
|
|
{
|
|
return getTableMetadata(descriptor.ksname, descriptor.cfname);
|
|
}
|
|
|
|
default TableMetadataRef getTableMetadataRef(Descriptor descriptor)
|
|
{
|
|
return getTableMetadata(descriptor.ksname, descriptor.cfname).ref;
|
|
}
|
|
|
|
default ViewMetadata getView(String keyspaceName, String viewName)
|
|
{
|
|
assert keyspaceName != null;
|
|
KeyspaceMetadata ksm = distributedKeyspaces().getNullable(keyspaceName);
|
|
return (ksm == null) ? null : ksm.views.getNullable(viewName);
|
|
}
|
|
|
|
default Keyspaces getNonLocalStrategyKeyspaces()
|
|
{
|
|
return distributedKeyspaces().filter(keyspace -> keyspace.params.replication.klass != LocalStrategy.class);
|
|
}
|
|
|
|
default TableMetadata validateTable(String keyspaceName, String tableName)
|
|
{
|
|
if (tableName.isEmpty())
|
|
throw new InvalidRequestException("non-empty table is required");
|
|
|
|
KeyspaceMetadata keyspace = getKeyspaceMetadata(keyspaceName);
|
|
if (keyspace == null)
|
|
throw new KeyspaceNotDefinedException(String.format("keyspace %s does not exist", keyspaceName));
|
|
|
|
TableMetadata metadata = keyspace.getTableOrViewNullable(tableName);
|
|
if (metadata == null)
|
|
throw new InvalidRequestException(String.format("table %s does not exist", tableName));
|
|
|
|
return metadata;
|
|
}
|
|
|
|
default ColumnFamilyStore getColumnFamilyStoreInstance(TableId id)
|
|
{
|
|
TableMetadata metadata = getTableMetadata(id);
|
|
if (metadata == null)
|
|
return null;
|
|
|
|
Keyspace instance = getKeyspaceInstance(metadata.keyspace);
|
|
if (instance == null)
|
|
return null;
|
|
|
|
return instance.hasColumnFamilyStore(metadata.id)
|
|
? instance.getColumnFamilyStore(metadata.id)
|
|
: null;
|
|
}
|
|
|
|
/**
|
|
* Get metadata about keyspace inner ColumnFamilies
|
|
*
|
|
* @param keyspaceName The name of the keyspace
|
|
* @return metadata about ColumnFamilies the belong to the given keyspace
|
|
*/
|
|
Iterable<TableMetadata> getTablesAndViews(String keyspaceName);
|
|
|
|
@Nullable
|
|
Keyspace getKeyspaceInstance(String keyspaceName);
|
|
|
|
@Nullable
|
|
KeyspaceMetadata getKeyspaceMetadata(String keyspaceName);
|
|
|
|
@Nullable
|
|
TableMetadata getTableMetadata(TableId id);
|
|
|
|
@Nullable
|
|
default IPartitioner getTablePartitioner(TableId id)
|
|
{
|
|
TableMetadata metadata = getTableMetadata(id);
|
|
return metadata == null ? null : metadata.partitioner;
|
|
}
|
|
|
|
default IPartitioner getExistingTablePartitioner(TableId id) throws UnknownTableException
|
|
{
|
|
return getExistingTableMetadata(id).partitioner;
|
|
}
|
|
|
|
@Nullable
|
|
default TableMetadataRef getTableMetadataRef(TableId id)
|
|
{
|
|
return getTableMetadata(id).ref;
|
|
}
|
|
|
|
@Nullable
|
|
TableMetadata getTableMetadata(String keyspace, String table);
|
|
|
|
default TableMetadataRef getTableMetadataRef(String keyspace, String table)
|
|
{
|
|
return getTableMetadata(keyspace, table).ref;
|
|
}
|
|
|
|
@Nullable
|
|
default ColumnMetadata getColumnMetadata(String keyspace, String table, ColumnIdentifier name)
|
|
{
|
|
TableMetadata metadata = getTableMetadata(keyspace, table);
|
|
if (metadata == null) return null;
|
|
return metadata.getColumn(name);
|
|
}
|
|
|
|
@Nullable
|
|
default ColumnMetadata getColumnMetadata(String keyspace, String table, ByteBuffer name)
|
|
{
|
|
TableMetadata metadata = getTableMetadata(keyspace, table);
|
|
if (metadata == null) return null;
|
|
return metadata.getColumn(name);
|
|
}
|
|
|
|
default TableMetadata getExistingTableMetadata(TableId id) throws UnknownTableException
|
|
{
|
|
TableMetadata metadata = getTableMetadata(id);
|
|
if (metadata != null)
|
|
return metadata;
|
|
|
|
String message =
|
|
String.format("Couldn't find table with id %s. If a table was just created, this is likely due to the schema "
|
|
+ "not being fully propagated. Please wait for schema agreement on table creation.",
|
|
id);
|
|
throw new UnknownTableException(message, id);
|
|
}
|
|
|
|
/* Function helpers */
|
|
|
|
/**
|
|
* Get all function overloads with the specified name
|
|
*
|
|
* @param name fully qualified function name
|
|
* @return an empty list if the keyspace or the function name are not found;
|
|
* a non-empty collection of {@link Function} otherwise
|
|
*/
|
|
default Collection<UserFunction> getUserFunctions(FunctionName name)
|
|
{
|
|
if (!name.hasKeyspace())
|
|
throw new IllegalArgumentException(String.format("Function name must be fully qualified: got %s", name));
|
|
|
|
KeyspaceMetadata ksm = getKeyspaceMetadata(name.keyspace);
|
|
return ksm == null
|
|
? Collections.emptyList()
|
|
: ksm.userFunctions.get(name);
|
|
}
|
|
|
|
/**
|
|
* Find the function with the specified name
|
|
*
|
|
* @param name fully qualified function name
|
|
* @param argTypes function argument types
|
|
* @return an empty {@link Optional} if the keyspace or the function name are not found;
|
|
* a non-empty optional of {@link Function} otherwise
|
|
*/
|
|
default Optional<UserFunction> findFunction(FunctionName name, List<AbstractType<?>> argTypes)
|
|
{
|
|
if (!name.hasKeyspace())
|
|
throw new IllegalArgumentException(String.format("Function name must be fully quallified: got %s", name));
|
|
|
|
KeyspaceMetadata ksm = getKeyspaceMetadata(name.keyspace);
|
|
return ksm == null
|
|
? Optional.empty()
|
|
: ksm.userFunctions.find(name, argTypes);
|
|
}
|
|
|
|
/**
|
|
* Compute the largest gc grace seconds amongst all the tables
|
|
* @return the largest gcgs.
|
|
*/
|
|
default int largestGcgs()
|
|
{
|
|
return distributedAndLocalKeyspaces().stream()
|
|
.flatMap(ksm -> ksm.tables.stream())
|
|
.mapToInt(tm -> tm.params.gcGraceSeconds)
|
|
.max()
|
|
.orElse(Integer.MIN_VALUE);
|
|
}
|
|
|
|
// TODO: remove?
|
|
public abstract void saveSystemKeyspace();
|
|
|
|
/**
|
|
* Find the function with the specified name and arguments.
|
|
*
|
|
* @param name fully qualified function name
|
|
* @param argTypes function argument types
|
|
* @return an empty {@link Optional} if the keyspace or the function name are not found;
|
|
* a non-empty optional of {@link Function} otherwise
|
|
*/
|
|
default Optional<UserFunction> findUserFunction(FunctionName name, List<AbstractType<?>> argTypes)
|
|
{
|
|
if (!name.hasKeyspace())
|
|
throw new IllegalArgumentException(String.format("Function name must be fully quallified: got %s", name));
|
|
|
|
return Optional.ofNullable(getKeyspaceMetadata(name.keyspace))
|
|
.flatMap(ksm -> ksm.userFunctions.find(name, argTypes));
|
|
}
|
|
}
|