Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ protected RiakFuture<Void, String> executeAsync(RiakCluster cluster)

public static class Builder extends CreateTableOperation.AbstractBuilder<CreateTable, Builder>
{
/**
* Creates a new Builder for the CreateTable command.
* If any quantum information is present in the {@code tableDefinition}'s column descriptions,
* it will be used automatically. If there is none present, please use
* {@link CreateTable.Builder#withQuantum(int, java.util.concurrent.TimeUnit)} to set the quantum information.
* @param tableDefinition The table definition to base this CreateTable command off of.
*/
public Builder(TableDefinition tableDefinition)
{
super(tableDefinition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.basho.riak.client.core.operations.PBFutureOperation;
import com.basho.riak.client.core.query.timeseries.ColumnDescription;
import com.basho.riak.client.core.query.timeseries.FullColumnDescription;
import com.basho.riak.client.core.query.timeseries.Quantum;
import com.basho.riak.client.core.query.timeseries.TableDefinition;
import com.basho.riak.protobuf.RiakMessageCodes;
import com.basho.riak.protobuf.RiakTsPB;
Expand Down Expand Up @@ -83,11 +84,11 @@ public AbstractBuilder(TableDefinition tableDefinition)
}

this.tableDefinition = tableDefinition;
findQuantumInfoInColumnDescriptions();
}

public abstract R build();


public CreateTableOperation buildOperation()
{
final String keys = generateKeys(tableDefinition, quantum, quantumUnit).toString();
Expand All @@ -105,35 +106,35 @@ public CreateTableOperation buildOperation()
return new CreateTableOperation(this);
}


/**
* Sets the quantum information for the partition key.
* If this method is used, it will override any quantum information included in
* the original TableDefinition passed into the Builder constructor.
* @param quantum The quantum interval
* @param tu The quantum time unit
* @return a reference to this object.
*/
@SuppressWarnings("unchecked")
public THIS withQuantum(int quantum, TimeUnit tu)
{
switch (tu)
{
case SECONDS:
quantumUnit = 's';
break;

case MINUTES:
quantumUnit = 'm';
break;

case HOURS:
quantumUnit = 'h';
break;
this.quantumUnit = Quantum.getTimeUnitChar(tu);
this.quantum = quantum;
return (THIS)this;
}

case DAYS:
quantumUnit = 'd';
break;
private void findQuantumInfoInColumnDescriptions()
{
for (FullColumnDescription fullColumnDescription : this.tableDefinition.getPartitionKeyColumnDescriptions())
{
if(!fullColumnDescription.hasQuantum())
{
continue;
}

default:
throw new IllegalArgumentException("Unsupported quantum unit '"+ tu.name() +"', at the moment the only:" +
" seconds, minutes, hours and days are supported.");
final Quantum quantum = fullColumnDescription.getQuantum();
this.quantum = quantum.getInterval();
this.quantumUnit = quantum.getUnitAsChar();
}

this.quantum = quantum;
return (THIS)this;
}

private static StringBuilder generateColumns(TableDefinition tableDefinition)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import com.google.protobuf.ByteString;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
* @author Alex Moore <amoore at basho dot com>
* @author Sergey Galkin <srggal at gmail dot com>
* @since 2.0.3
*/
public final class CollectionConverters
final class CollectionConverters
{
private CollectionConverters() {}

Expand Down Expand Up @@ -64,60 +65,4 @@ private static ColumnDescription convertPBColumnDescription(RiakTsPB.TsColumnDes

return new ColumnDescription(name, type);
}

public static List<FullColumnDescription> convertDescribeQueryResultToColumnDescriptions(QueryResult queryResult)
{
final List<FullColumnDescription> fullColumnDescriptions = new ArrayList<>(queryResult.getRowsCount());

for (Row row : queryResult)
{
fullColumnDescriptions.add(convertDescribeResultRowToFullColumnDescription(row));
}

return fullColumnDescriptions;
}

private static FullColumnDescription convertDescribeResultRowToFullColumnDescription(Row row)
{
/*
* Expected Format for the DESCRIBE function is 5 columns:
*
* "Column" (non-null Varchar)
* "Type" (non-null Varchar)
* "Is Null" (non-null Boolean)
* "Partition Key" (nullable SInt64)
* "Local Key" (nullable SInt64)
*/

final List<Cell> cells = row.getCellsCopy();

assert(DescribeFnRowResultIsValid(cells));

final String name = cells.get(0).getVarcharAsUTF8String();
final String typeString = cells.get(1).getVarcharAsUTF8String();
final boolean isNullable = cells.get(2).getBoolean();
final boolean isPartitionKeyMember = cells.get(3) != null;
final boolean isLocalKeyMember = cells.get(4) != null;
final Integer partitionKeyOrdinal = isPartitionKeyMember ? new Long(cells.get(3).getLong()).intValue() : null;
final Integer localKeyOrdinal = isLocalKeyMember ? new Long(cells.get(4).getLong()).intValue() : null;

final ColumnDescription.ColumnType type =
ColumnDescription.ColumnType.valueOf(typeString.toUpperCase(Locale.ENGLISH));

return new FullColumnDescription(name,
type,
isNullable,
partitionKeyOrdinal,
localKeyOrdinal);
}

private static boolean DescribeFnRowResultIsValid(List<Cell> cells)
{
return cells.size() == 5 &&
cells.get(0).hasVarcharValue() &&
cells.get(1).hasVarcharValue() &&
cells.get(2).hasBoolean() &&
cells.get(3) != null ? cells.get(3).hasLong() : true &&
cells.get(4) != null ? cells.get(4).hasLong() : true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright 2013-2016 Basho Technologies Inc
*
* Licensed 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.basho.riak.client.core.query.timeseries;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
* Parses DESCRIBE query results into {@link FullColumnDescription}s.
* <p>
* Expected Format for the DESCRIBE function is 5 or 7 columns depending on the version.
* <p>
* V1 includes:
* "Column" (non-null Varchar)
* "Type" (non-null Varchar)
* "Is Null" (non-null Boolean)
* "Partition Key" (nullable SInt64)
* "Local Key" (nullable SInt64)
* <p>
* V2 also includes:
* "Interval", part of the quantum information (nullable SInt64)
* "Unit", part of the quantum information (nullable Varchar), either 'd', 'h', 'm', or 's'
*
* @author Alex Moore <amoore at basho dot com>
* @since 2.0.7
*/

class DescribeQueryResultParser
{
private final static int NAME_IDX = 0;
private final static int TYPE_IDX = 1;
private final static int NULLABLE_IDX = 2;
private final static int PARTITION_KEY_IDX = 3;
private final static int LOCAL_KEY_IDX = 4;
private final static int QUANTUM_INTERVAL_IDX = 5;
private final static int QUANTUM_UNIT_IDX = 6;

static List<FullColumnDescription> ConvertToColumnDescriptions(QueryResult queryResult)
{
final List<FullColumnDescription> fullColumnDescriptions = new ArrayList<>(queryResult.getRowsCount());

for (Row row : queryResult)
{
fullColumnDescriptions.add(convertDescribeResultRowToFullColumnDescription(row));
}

return fullColumnDescriptions;
}

private static FullColumnDescription convertDescribeResultRowToFullColumnDescription(Row row)
{
final List<Cell> cells = row.getCellsCopy();

assert (DescribeFnRowResultIsValid(cells));

final String name = cells.get(NAME_IDX).getVarcharAsUTF8String();
final String typeString = cells.get(TYPE_IDX).getVarcharAsUTF8String();
final boolean isNullable = cells.get(NULLABLE_IDX).getBoolean();

final Integer partitionKeyOrdinal = parseKeyCell(cells.get(PARTITION_KEY_IDX));
final Integer localKeyOrdinal = parseKeyCell(cells.get(LOCAL_KEY_IDX));

final ColumnDescription.ColumnType type =
ColumnDescription.ColumnType.valueOf(typeString.toUpperCase(Locale.ENGLISH));

final Quantum quantum = parseQuantumCells(cells);

return new FullColumnDescription(name, type, isNullable, partitionKeyOrdinal, localKeyOrdinal, quantum);
}

private static Integer parseKeyCell(Cell keyCell)
{
final boolean isKeyMember = keyCell != null;
return isKeyMember ? new Long(keyCell.getLong()).intValue() : null;
}

private static Quantum parseQuantumCells(List<Cell> cells)
{
if (cells.size() < 7)
{
return null;
}

final Cell quantumIntervalCell = cells.get(QUANTUM_INTERVAL_IDX);
final Cell quantumUnitCell = cells.get(QUANTUM_UNIT_IDX);

final boolean hasQuantum = quantumIntervalCell != null && quantumUnitCell != null;

if (!hasQuantum)
{
return null;
}

final Long quantumInterval = quantumIntervalCell.getLong();
final TimeUnit quantumUnit = Quantum.parseTimeUnit(quantumUnitCell.getVarcharAsUTF8String());

return new Quantum(quantumInterval.intValue(), quantumUnit);
}

private static boolean DescribeFnRowResultIsValid(List<Cell> cells)
{
final boolean describeBaseIsValid = DescribeRowV1ChunkIsValid(cells);
final boolean isValidV1Description = describeBaseIsValid && cells.size() == 5;
final boolean isValidV2Description =
describeBaseIsValid && cells.size() == 7 && DescribeRowV2ChunkIsValid(cells);

return isValidV1Description || isValidV2Description;
}

private static boolean DescribeRowV1ChunkIsValid(List<Cell> cells)
{
if(cells.size() < 5)
{
return false;
}

final Cell partitionKeyCell = cells.get(PARTITION_KEY_IDX);
final Cell localKeyCell = cells.get(LOCAL_KEY_IDX);

return cells.get(NAME_IDX).hasVarcharValue() &&
cells.get(TYPE_IDX).hasVarcharValue() &&
cells.get(NULLABLE_IDX).hasBoolean() &&
partitionKeyCell != null ? partitionKeyCell.hasLong() : true &&
localKeyCell != null ? localKeyCell.hasLong() : true;
}

private static boolean DescribeRowV2ChunkIsValid(List<Cell> cells)
{
if(cells.size() < 7)
{
return false;
}

final Cell quantumIntervalCell = cells.get(QUANTUM_INTERVAL_IDX);
final Cell quantumUnitCell = cells.get(QUANTUM_UNIT_IDX);

return quantumIntervalCell != null ? quantumIntervalCell.hasLong() : true &&
quantumUnitCell != null ? quantumUnitCell.hasVarcharValue() : true;
}
}
Loading