Skip to content
This repository was archived by the owner on Aug 13, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions RELNOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Release Notes
=============

### 2.1.1

Following issues / PRs addressed:

* [Added TS 1.5 Feature Support](https://github.com/basho/riak-java-client/pull/691)

### 2.1.0

**Notes**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public static OtpOutputStream encodeTsQueryRequest(String queryText, byte[] cove
final OtpOutputStream os = new OtpOutputStream();
os.write(OtpExternal.versionTag); // NB: this is the reqired 0x83 (131) value

// TsQueryReq is a 4-tuple: {'tsqueryreq', TsInt, boolIsStreaming, bytesCoverContext}
// TsQueryReq is a 4-tuple: {'tsqueryreq', TsInterpolation, boolIsStreaming, bytesCoverContext}
os.write_tuple_head(4);
os.write_atom(TS_QUERY_REQ);

Expand Down Expand Up @@ -171,6 +171,10 @@ else if (cell.hasDouble())
{
stream.write_double(cell.getDouble());
}
else if(cell.hasBlob())
{
stream.write_binary(cell.getBlob());
}
else
{
logger.error("Unknown TS cell type encountered.");
Expand All @@ -181,11 +185,9 @@ else if (cell.hasDouble())
private static QueryResult decodeTsResponse(byte[] response)
throws OtpErlangDecodeException, InvalidTermToBinaryException
{
QueryResult result = null;

OtpInputStream is = new OtpInputStream(response);
final OtpInputStream is = new OtpInputStream(response);

int firstByte = is.read1skip_version();
final int firstByte = is.read1skip_version();
is.reset();

if (firstByte != OtpExternal.smallTupleTag && firstByte != OtpExternal.largeTupleTag)
Expand Down Expand Up @@ -213,7 +215,7 @@ private static QueryResult parseAtomResult(OtpInputStream is)
private static QueryResult parseTupleResult(OtpInputStream is)
throws OtpErlangDecodeException, InvalidTermToBinaryException
{
QueryResult result;
final QueryResult result;
final int msgArity = is.read_tuple_head();
// Response is:
// {'rpberrorresp', ErrMsg, ErrCode}
Expand Down Expand Up @@ -322,30 +324,37 @@ private static Cell parseCell(List<RiakTsPB.TsColumnDescription> columnDescripti
{
if (cell instanceof OtpErlangBinary)
{
OtpErlangBinary v = (OtpErlangBinary) cell;
String s = new String(v.binaryValue(), StandardCharsets.UTF_8);
return new Cell(s);
final OtpErlangBinary v = (OtpErlangBinary) cell;
if (columnDescriptions.get(j).getType() == RiakTsPB.TsColumnType.VARCHAR)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO better to throw exception in case when something is incompatible, rather then silently skip it:

switch(columnDescriptions.get(j).getType()){
  case RiakTsPB.TsColumnType.VARCHAR://
  case RiakTsPB.TsColumnType.BLOB: //
  default:
    throw new IllegalStateException(<proper explanation>)
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do fall through to the "default" case on line 367 / 368 where we throw an exception, but I guess it could be more specific.

{
final String s = new String(v.binaryValue(), StandardCharsets.UTF_8);
return new Cell(s);
}
else if (columnDescriptions.get(j).getType() == RiakTsPB.TsColumnType.BLOB)
{
return new Cell(v.binaryValue());
}
}
else if (cell instanceof OtpErlangLong)
{
OtpErlangLong v = (OtpErlangLong) cell;
final OtpErlangLong v = (OtpErlangLong) cell;
if (columnDescriptions.get(j).getType() == RiakTsPB.TsColumnType.TIMESTAMP)
{
return Cell.newTimestamp(v.longValue());
}
else
else if (columnDescriptions.get(j).getType() == RiakTsPB.TsColumnType.SINT64)
{
return new Cell(v.longValue());
}
}
else if (cell instanceof OtpErlangDouble)
{
OtpErlangDouble v = (OtpErlangDouble) cell;
final OtpErlangDouble v = (OtpErlangDouble) cell;
return new Cell(v.doubleValue());
}
else if (cell instanceof OtpErlangAtom)
{
OtpErlangAtom v = (OtpErlangAtom) cell;
final OtpErlangAtom v = (OtpErlangAtom) cell;
return new Cell(v.booleanValue());
}
else if (cell instanceof OtpErlangList)
Expand All @@ -354,10 +363,8 @@ else if (cell instanceof OtpErlangList)
assert (l.arity() == 0);
return null;
}
else
{
throw new InvalidTermToBinaryException("Unknown cell type encountered: " + cell.toString() + ", unable to" +
" continue parsing.");
}

throw new InvalidTermToBinaryException("Unknown cell type encountered: " + cell.toString() +
", unable to continue parsing.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
*/
public class CreateTableOperation extends PBFutureOperation<Void, RiakTsPB.TsQueryResp, String>
{
private final RiakTsPB.TsQueryReq.Builder reqBuilder;
private final String queryText;

private CreateTableOperation(AbstractBuilder builder)
Expand All @@ -46,7 +45,6 @@ private CreateTableOperation(AbstractBuilder builder)
builder.reqBuilder,
RiakTsPB.TsQueryResp.PARSER);

this.reqBuilder = builder.reqBuilder;
this.queryText = builder.queryText;
}

Expand Down Expand Up @@ -205,6 +203,12 @@ private static StringBuilder generateKeys(TableDefinition tableDefinition, int q
{
sb.append(", ")
.append(lk.getName());

if (lk.hasKeyOrder())
{
sb.append(" ");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be (but not mandatory) re-written like:

sb.append(" ")
    .append(lk.getKeyOrder().toString());

sb.append(lk.getKeyOrder().toString());
}
}

return sb;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.basho.riak.client.core.query;

import com.basho.riak.protobuf.RiakTsPB;

import java.util.Iterator;

/**
* @author Sergey Galkin <srggal at gmail dot com>
* @author Alex Moore <amoore at basho dot com>
* @since 2.0.3
*/
public abstract class ConvertibleIterator<S,D> implements Iterator<D> {
private final Iterator<S> iterator;
public abstract class ConvertibleIterator<S,D> implements Iterator<D>
{
protected final Iterator<S> iterator;

public ConvertibleIterator(Iterator<S> iterator) {
this.iterator = iterator;
Expand All @@ -19,17 +18,17 @@ public ConvertibleIterator(Iterator<S> iterator) {
abstract protected D convert(S source);

@Override
public final boolean hasNext() {
public boolean hasNext() {
return iterator.hasNext();
}

@Override
public final D next() {
public D next() {
return convert(iterator.next());
}

@Override
public final void remove() {
throw new UnsupportedOperationException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
import com.basho.riak.protobuf.RiakTsPB;
import com.google.protobuf.ByteString;

import javax.xml.bind.DatatypeConverter;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

/**
* Holds a piece of data for a Time Series @{link Row}.
* A cell can hold 5 different types of raw data:
* A cell can hold 6 different types of raw data:
* <ol>
* <li><b>Varchar</b>s, which can hold byte arrays. Commonly used to store encoded strings.</li>
* <li><b>SInt64</b>s, which can hold any signed 64-bit integers.</li>
* <li><b>Double</b>s, which can hold any 64-bit floating point numbers.</li>
* <li><b>Timestamp</b>s, which can hold any unix/epoch timestamp. Millisecond resolution is required.</li>
* <li><b>Boolean</b>s, which can hold a true/false value. </li>
* <li><b>Blob</b>s, which can hold any binary data.</li>
* </ol>
* Immutable once created.
*
Expand All @@ -32,13 +35,15 @@ public class Cell
private static final int DOUBLE_MASK = 0x00000004;
private static final int TIMESTAMP_MASK = 0x00000008;
private static final int BOOLEAN_MASK = 0x00000010;
private static final int BLOB_MASK = 0x00000011;
private int typeBitfield = 0x0;

private String varcharValue = "";
private long sint64Value = 0L;
private double doubleValue = 0.0;
private long timestampValue = 0L;
private boolean booleanValue = false;
private byte[] blobValue = {};

/**
* Creates a new "Varchar" Cell, based on the UTF8 binary encoding of the provided String.
Expand Down Expand Up @@ -130,7 +135,22 @@ public Cell(Date timestampValue)
initTimestamp(timestampValue.getTime());
}

Cell(RiakTsPB.TsCell pbCell)
/**
* Creates a new "Blob" Cell from the provided byte array.
*
* @param blobValue The blob to store.
*/
public Cell(byte[] blobValue)
{
if (blobValue == null)
{
throw new IllegalArgumentException("Value for BLOB value cannot be NULL.");
}

initBlob(blobValue);
}

Cell(RiakTsPB.TsCell pbCell, RiakTsPB.TsColumnDescription columnDescription)
{
if (pbCell.hasBooleanValue())
{
Expand All @@ -148,10 +168,14 @@ else if (pbCell.hasTimestampValue())
{
initTimestamp(pbCell.getTimestampValue());
}
else if (pbCell.hasVarcharValue())
else if (pbCell.hasVarcharValue() && columnDescription.getType() == RiakTsPB.TsColumnType.VARCHAR)
{
initVarchar(pbCell.getVarcharValue().toStringUtf8());
}
else if (pbCell.hasVarcharValue() && columnDescription.getType() == RiakTsPB.TsColumnType.BLOB)
{
initBlob(pbCell.getVarcharValue().toByteArray());
}
else
{
throw new IllegalArgumentException("Unknown PB Cell encountered.");
Expand Down Expand Up @@ -205,14 +229,20 @@ private void initVarchar(String stringValue)
this.varcharValue = stringValue;
}

private void initBlob(byte[] blobValue)
{
setBitfieldType(BLOB_MASK);
this.blobValue = blobValue;
}

private void setBitfieldType(int mask)
{
typeBitfield |= mask;
}

private boolean bitfieldHasType(int mask)
{
return (typeBitfield & mask) == mask;
return typeBitfield == mask;
}

public boolean hasVarcharValue()
Expand Down Expand Up @@ -240,6 +270,11 @@ public boolean hasBoolean()
return bitfieldHasType(BOOLEAN_MASK);
}

public boolean hasBlob()
{
return bitfieldHasType(BLOB_MASK);
}

public String getVarcharAsUTF8String()
{
return varcharValue;
Expand Down Expand Up @@ -270,6 +305,11 @@ public boolean getBoolean()
return booleanValue;
}

public byte[] getBlob()
{
return blobValue;
}

RiakTsPB.TsCell getPbCell()
{
final RiakTsPB.TsCell.Builder builder = RiakTsPB.TsCell.newBuilder();
Expand All @@ -294,6 +334,10 @@ else if (hasDouble())
{
builder.setDoubleValue(doubleValue);
}
else if(hasBlob())
{
builder.setVarcharValue(ByteString.copyFrom(blobValue));
}

return builder.build();
}
Expand Down Expand Up @@ -332,6 +376,13 @@ else if (this.hasBoolean())
{
sb.append(this.getBoolean());
}
else if (this.hasBlob())
{
final int length = blobValue.length > 8 ? 8 : blobValue.length;
final byte[] blobBlurb = Arrays.copyOfRange(blobValue, 0, length);
sb.append("0x");
sb.append(DatatypeConverter.printHexBinary(blobBlurb));
}

sb.append(" }");
return sb.toString();
Expand All @@ -351,6 +402,10 @@ public boolean equals(Object o)

Cell cell = (Cell) o;

if (typeBitfield != cell.typeBitfield)
{
return false;
}
if (sint64Value != cell.sint64Value)
{
return false;
Expand All @@ -367,25 +422,27 @@ public boolean equals(Object o)
{
return false;
}
if (typeBitfield != cell.typeBitfield)
if (varcharValue != null ? !varcharValue.equals(cell.varcharValue) : cell.varcharValue != null)
{
return false;
}
return varcharValue.equals(cell.varcharValue);
return Arrays.equals(blobValue, cell.blobValue);

}

@Override
public int hashCode()
{
int result;
long temp;
result = varcharValue.hashCode();
result = typeBitfield;
result = 31 * result + (varcharValue != null ? varcharValue.hashCode() : 0);
result = 31 * result + (int) (sint64Value ^ (sint64Value >>> 32));
temp = Double.doubleToLongBits(doubleValue);
result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (int) (timestampValue ^ (timestampValue >>> 32));
result = 31 * result + (booleanValue ? 1 : 0);
result = 31 * result + typeBitfield;
result = 31 * result + Arrays.hashCode(blobValue);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public enum ColumnType
SINT64,
DOUBLE,
TIMESTAMP,
BOOLEAN
BOOLEAN,
BLOB
}

@Override
Expand Down
Loading