package org.apache.hadoop.hive.cassandra.serde;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import org.apache.hadoop.hive.cassandra.output.CassandraColumn;
import org.apache.hadoop.hive.cassandra.output.CassandraPut;
import org.apache.hadoop.hive.cassandra.output.CassandraSuperPut;
import org.apache.hadoop.hive.serde2.SerDeException;
import org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe.SerDeParameters;
import org.apache.hadoop.hive.serde2.objectinspector.StructField;
import org.apache.hadoop.io.Writable;
public class TransposedMapping extends TableMapping {
/* Track the index of :column, :subcolumn, and :value. This would only be set when it is a transposed table*/
private int columnName = -1;
private int columnValue = -1;
private int subColumnName = -1;
public TransposedMapping(
String colFamily,
List<String> columnNames,
SerDeParameters serdeParams) throws SerDeException {
super(colFamily, columnNames, serdeParams);
init();
}
private void init() throws SerDeException {
setTransposedTableIndex();
}
@Override
public Writable write(
byte[] keyBytes,
List<? extends StructField> fields,
List<Object> list,
List<? extends StructField> declaredFields) throws IOException {
assert columnName >= 0;
assert columnValue >= 0;
if (subColumnName == -1) {
//A regular column family mapping
CassandraPut put = new CassandraPut(ByteBuffer.wrap(keyBytes));
CassandraColumn cc = new CassandraColumn();
cc.setTimeStamp(System.currentTimeMillis());
cc.setColumnFamily(cassandraColumnFamily);
cc.setColumn(serializeToBytes(columnName, fields, list, declaredFields));
cc.setValue(serializeToBytes(columnValue, fields, list, declaredFields));
put.getColumns().add(cc);
return put;
} else {
//A super column family mapping
//This is a super column family mapping
CassandraSuperPut put = new CassandraSuperPut(ByteBuffer.wrap(keyBytes));
byte[] colName = serializeToBytes(
fields.get(columnName).getFieldObjectInspector(),
declaredFields.get(columnName).getFieldObjectInspector(),
list.get(columnName),
useJsonSerialize(columnName, declaredFields));
CassandraPut column = new CassandraPut(ByteBuffer.wrap(colName));
CassandraColumn cc = new CassandraColumn();
cc.setTimeStamp(System.currentTimeMillis());
cc.setColumnFamily(cassandraColumnFamily);
cc.setColumn(serializeToBytes(subColumnName, fields, list, declaredFields));
cc.setValue(serializeToBytes(columnValue, fields, list, declaredFields));
column.getColumns().add(cc);
put.getColumns().add(column);
return put;
}
}
/**
* Save the index of :column, :value and :subcolumn and the transposedTable flag if and only if this is a transposed table.
*
* @throws SerDeException
*/
private void setTransposedTableIndex() throws SerDeException {
int key = -1;
int columnName = -1;
int columnValue = -1;
int subColumnName = -1;
for (int i = 0; i < cassandraColumnNames.size(); i++) {
String str = cassandraColumnNames.get(i);
if (str.equals(AbstractColumnSerDe.CASSANDRA_KEY_COLUMN)) {
key = i;
} else if (str.equals(AbstractColumnSerDe.CASSANDRA_COLUMN_COLUMN)) {
columnName = i;
} else if (str.equals(AbstractColumnSerDe.CASSANDRA_VALUE_COLUMN)) {
columnValue = i;
} else if (str.equals(AbstractColumnSerDe.CASSANDRA_SUBCOLUMN_COLUMN)) {
subColumnName = i;
} else {
throw new SerDeException("An expected mapping appears in the column mapping " + str);
}
}
if (key >= 0 && columnName >= 0 && columnValue >= 0) {
if (subColumnName != -1) {
this.subColumnName = subColumnName;
}
this.columnName = columnName;
this.columnValue = columnValue;
}
}
}