package com.datastax.oss.driver.internal.core.metadata.schema.parsing;
import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.metadata.schema.RelationMetadata;
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
import com.datastax.oss.driver.api.core.type.codec.TypeCodecs;
import com.datastax.oss.driver.internal.core.adminrequest.AdminRow;
import com.datastax.oss.driver.internal.core.context.InternalDriverContext;
import com.datastax.oss.driver.internal.core.metadata.schema.ScriptBuilder;
import com.datastax.oss.driver.internal.core.metadata.schema.queries.SchemaRows;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap;
import java.nio.ByteBuffer;
import java.util.Map;
import net.jcip.annotations.ThreadSafe;
@ThreadSafe
public abstract class RelationParser {
protected final SchemaRows rows;
protected final InternalDriverContext context;
protected final String logPrefix;
protected RelationParser(SchemaRows rows, InternalDriverContext context) {
this.rows = rows;
this.context = context;
this.logPrefix = context.getSessionName();
}
protected Map<CqlIdentifier, Object> parseOptions(AdminRow row) {
ImmutableMap.Builder<CqlIdentifier, Object> builder = ImmutableMap.builder();
for (Map.Entry<String, TypeCodec<?>> entry : OPTION_CODECS.entrySet()) {
String name = entry.getKey();
CqlIdentifier id = CqlIdentifier.fromInternal(name);
TypeCodec<?> codec = entry.getValue();
if (name.equals("caching") && row.isString("caching")) {
builder.put(id, row.getString(name));
} else if (name.equals("compaction_strategy_class")) {
String strategyClass = row.getString(name);
if (strategyClass != null) {
builder.put(
CqlIdentifier.fromInternal("compaction"),
ImmutableMap.<String, String>builder()
.put("class", strategyClass)
.putAll(
SimpleJsonParser.parseStringMap(row.getString("compaction_strategy_options")))
.build());
}
} else if (name.equals("compression_parameters")) {
String compressionParameters = row.getString(name);
if (compressionParameters != null) {
builder.put(
CqlIdentifier.fromInternal("compression"),
ImmutableMap.copyOf(SimpleJsonParser.parseStringMap(row.getString(name))));
}
} else {
Object value = row.get(name, codec);
if (value != null) {
builder.put(id, value);
}
}
}
return builder.build();
}
public static void appendOptions(Map<CqlIdentifier, Object> options, ScriptBuilder builder) {
for (Map.Entry<CqlIdentifier, Object> entry : options.entrySet()) {
CqlIdentifier name = entry.getKey();
Object value = entry.getValue();
String formattedValue;
if (name.asInternal().equals("caching") && value instanceof String) {
formattedValue = TypeCodecs.TEXT.format((String) value);
} else {
@SuppressWarnings("unchecked")
TypeCodec<Object> codec =
(TypeCodec<Object>) RelationParser.OPTION_CODECS.get(name.asInternal());
formattedValue = codec.format(value);
}
String optionName = name.asCql(true);
if ("local_read_repair_chance".equals(optionName)) {
optionName = "dclocal_read_repair_chance";
}
builder.andWith().append(optionName).append(" = ").append(formattedValue);
}
}
public static final TypeCodec<Map<String, String>> MAP_OF_TEXT_TO_TEXT =
TypeCodecs.mapOf(TypeCodecs.TEXT, TypeCodecs.TEXT);
private static final TypeCodec<Map<String, ByteBuffer>> MAP_OF_TEXT_TO_BLOB =
TypeCodecs.mapOf(TypeCodecs.TEXT, TypeCodecs.BLOB);
public static final ImmutableMap<String, TypeCodec<?>> OPTION_CODECS =
ImmutableMap.<String, TypeCodec<?>>builder()
.put("additional_write_policy", TypeCodecs.TEXT)
.put("bloom_filter_fp_chance", TypeCodecs.DOUBLE)
.put("caching", MAP_OF_TEXT_TO_TEXT)
.put("cdc", TypeCodecs.BOOLEAN)
.put("comment", TypeCodecs.TEXT)
.put("compaction", MAP_OF_TEXT_TO_TEXT)
.put("compaction_strategy_class", TypeCodecs.TEXT)
.put("compression", MAP_OF_TEXT_TO_TEXT)
.put("compression_parameters", TypeCodecs.TEXT)
.put("crc_check_chance", TypeCodecs.DOUBLE)
.put("dclocal_read_repair_chance", TypeCodecs.DOUBLE)
.put("default_time_to_live", TypeCodecs.INT)
.put("extensions", MAP_OF_TEXT_TO_BLOB)
.put("gc_grace_seconds", TypeCodecs.INT)
.put("local_read_repair_chance", TypeCodecs.DOUBLE)
.put("max_index_interval", TypeCodecs.INT)
.put("memtable_flush_period_in_ms", TypeCodecs.INT)
.put("min_index_interval", TypeCodecs.INT)
.put("read_repair", TypeCodecs.TEXT)
.put("read_repair_chance", TypeCodecs.DOUBLE)
.put("speculative_retry", TypeCodecs.TEXT)
.build();
}