/*
* 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.usergrid.persistence.core.datastax.impl;
import com.datastax.driver.core.DataType;
import com.google.common.base.Preconditions;
import org.apache.usergrid.persistence.core.CassandraFig;
import org.apache.usergrid.persistence.core.datastax.TableDefinition;
import org.apache.usergrid.persistence.core.util.StringUtils;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
import static org.apache.usergrid.persistence.core.datastax.CQLUtils.*;
public class TableDefinitionImpl implements TableDefinition {
public enum CacheOption {
ALL, KEYS, ROWS, NONE
}
private final String keyspace;
private final String tableName;
private final Collection<String> partitionKeys;
private final Collection<String> columnKeys;
private final Map<String, DataType.Name> columns;
private final CacheOption cacheOption;
private final Map<String, Object> compaction;
private final String bloomFilterChance;
private final String readRepairChance;
private final Map<String, Object> compression;
private final String gcGraceSeconds;
private final Map<String, String> clusteringOrder;
static String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS";
static String ALTER_TABLE = "ALTER TABLE";
static String WITH ="WITH";
static String AND = "AND";
static String EQUAL = "=";
static String COMPRESSION = "compression";
static String COMPACTION = "compaction";
static String CACHING = "caching";
static String GC_GRACE_SECONDS = "gc_grace_seconds";
static String PRIMARY_KEY = "PRIMARY KEY";
static String COMPACT_STORAGE = "COMPACT STORAGE";
static String CLUSTERING_ORDER_BY = "CLUSTERING ORDER BY";
static String COMMA = ",";
static String PAREN_LEFT = "(";
static String PAREN_RIGHT = ")";
static String COMPOSITE_TYPE = "'org.apache.cassandra.db.marshal.DynamicCompositeType(a=>org.apache.cassandra.db.marshal.AsciiType,A=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.AsciiType),b=>org.apache.cassandra.db.marshal.BytesType,B=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.BytesType),i=>org.apache.cassandra.db.marshal.IntegerType,I=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.IntegerType),l=>org.apache.cassandra.db.marshal.LongType,L=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.LongType),s=>org.apache.cassandra.db.marshal.UTF8Type,S=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UTF8Type),t=>org.apache.cassandra.db.marshal.TimeUUIDType,T=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.TimeUUIDType),u=>org.apache.cassandra.db.marshal.UUIDType,U=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UUIDType),x=>org.apache.cassandra.db.marshal.LexicalUUIDType,X=>org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.LexicalUUIDType))'";
public TableDefinitionImpl(
final String keyspace,
final String tableName,
final Collection<String> partitionKeys,
final Collection<String> columnKeys,
final Map<String, DataType.Name> columns,
final CacheOption cacheOption,
final Map<String, String> clusteringOrder) {
Preconditions.checkNotNull(tableName, "Table name cannot be null");
Preconditions.checkNotNull(partitionKeys, "Primary Key(s) cannot be null");
Preconditions.checkNotNull(columns, "Columns cannot be null");
Preconditions.checkNotNull(cacheOption, "CacheOption cannot be null");
this.keyspace = keyspace;
this.tableName = tableName;
this.partitionKeys = partitionKeys;
this.columnKeys = columnKeys;
this.columns = columns;
this.cacheOption = cacheOption;
this.clusteringOrder = clusteringOrder;
// this are default settings always used
this.compaction = new HashMap<>(1);
compaction.put( "class", "LeveledCompactionStrategy" );
this.bloomFilterChance = "0.1d";
this.readRepairChance = "0.1d";
this.compression = new HashMap<>(1);
compression.put("sstable_compression", "LZ4Compressor");
this.gcGraceSeconds = "864000";
}
@Override
public String getKeyspace() {
return keyspace;
}
public String getTableName() {
return tableName;
}
@Override
public String getTableCQL(CassandraFig cassandraFig, ACTION tableAction) throws Exception {
StringJoiner cql = new StringJoiner(" ");
if ( tableAction.equals( ACTION.CREATE) ){
cql.add(CREATE_TABLE);
} else if ( tableAction.equals( ACTION.UPDATE) ){
cql.add(ALTER_TABLE);
}else{
throw new Exception("Invalid Action specified. Must of of type CQLUtils.Action");
}
cql.add( getTableName() );
if ( tableAction.equals( ACTION.CREATE) ){
cql.add(PAREN_LEFT).add( spaceSeparatedKeyValue( getColumns()) ).add(COMMA)
.add(PRIMARY_KEY)
.add(PAREN_LEFT).add(PAREN_LEFT)
.add( StringUtils.join(getPartitionKeys(), COMMA) ).add(PAREN_RIGHT);
if ( getColumnKeys() != null && !getColumnKeys().isEmpty() ){
cql.add(COMMA).add( StringUtils.join(getColumnKeys(), COMMA) );
}
cql.add(PAREN_RIGHT).add(PAREN_RIGHT)
.add(WITH)
.add(CLUSTERING_ORDER_BY)
.add(PAREN_LEFT)
.add( spaceSeparatedKeyValue(getClusteringOrder()) )
.add(PAREN_RIGHT)
.add(AND)
.add(COMPACT_STORAGE)
.add(AND);
} else if ( tableAction.equals( ACTION.UPDATE) ){
cql.add(WITH);
}
cql.add(COMPACTION).add(EQUAL).add( getMapAsCQLString( getCompaction() ) )
.add(AND)
.add(COMPRESSION).add(EQUAL).add( getMapAsCQLString( getCompression() ) )
.add(AND)
.add(GC_GRACE_SECONDS).add(EQUAL).add( getGcGraceSeconds() )
.add(AND)
.add(CACHING).add(EQUAL).add( getCachingOptions( cassandraFig, getCacheOption() ) );
return cql.toString();
}
public Collection<String> getPartitionKeys() {
return partitionKeys;
}
public Collection<String> getColumnKeys() {
return columnKeys;
}
public Map<String, DataType.Name> getColumns() {
return columns;
}
public CacheOption getCacheOption() {
return cacheOption;
}
public Map<String, Object> getCompaction() {
return compaction;
}
public String getBloomFilterChance() {
return bloomFilterChance;
}
public String getReadRepairChance() {
return readRepairChance;
}
public Map<String, Object> getCompression() {
return compression;
}
public String getGcGraceSeconds() {
return gcGraceSeconds;
}
public Map<String, String> getClusteringOrder() {
return clusteringOrder;
}
}