You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/09/17 02:10:48 UTC
[2/8] incubator-calcite git commit: [CALCITE-840] Protocol buffer
serialization over HTTP for Avatica Server (Josh Elser)
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
index 1171d76..e78aa2e 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/Service.java
@@ -17,15 +17,24 @@
package org.apache.calcite.avatica.remote;
import org.apache.calcite.avatica.AvaticaConnection;
+import org.apache.calcite.avatica.ConnectionPropertiesImpl;
import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.proto.Responses;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Message;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
/**
* API for request-response calls to an Avatica server.
@@ -77,6 +86,8 @@ public interface Service {
@JsonSubTypes.Type(value = DatabasePropertyRequest.class, name = "databaseProperties") })
abstract class Request {
abstract Response accept(Service service);
+ abstract Request deserialize(Message genericMsg);
+ abstract Message serialize();
}
/** Base class for all service response messages. */
@@ -97,6 +108,8 @@ public interface Service {
@JsonSubTypes.Type(value = ConnectionSyncResponse.class, name = "connectionSync"),
@JsonSubTypes.Type(value = DatabasePropertyResponse.class, name = "databaseProperties") })
abstract class Response {
+ abstract Response deserialize(Message genericMsg);
+ abstract Message serialize();
}
/** Request for
@@ -105,6 +118,31 @@ public interface Service {
ResultSetResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override CatalogsRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.CatalogsRequest)) {
+ throw new IllegalArgumentException(
+ "Expected CatalogsRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ // No state to set
+ return new CatalogsRequest();
+ }
+
+ @Override Requests.CatalogsRequest serialize() {
+ return Requests.CatalogsRequest.newBuilder().build();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ return o instanceof CatalogsRequest;
+ }
}
/** Request for
@@ -117,14 +155,42 @@ public interface Service {
DatabasePropertyResponse accept(Service service) {
return service.apply(this);
}
- }
+ @Override DatabasePropertyRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.DatabasePropertyRequest)) {
+ throw new IllegalArgumentException(
+ "Expected DatabasePropertyRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ return new DatabasePropertyRequest();
+ }
+
+ @Override Requests.DatabasePropertyRequest serialize() {
+ return Requests.DatabasePropertyRequest.newBuilder().build();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ return o instanceof DatabasePropertyRequest;
+ }
+ }
/** Request for
* {@link Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}. */
class SchemasRequest extends Request {
public final String catalog;
public final String schemaPattern;
+ SchemasRequest() {
+ catalog = null;
+ schemaPattern = null;
+ }
+
@JsonCreator
public SchemasRequest(@JsonProperty("catalog") String catalog,
@JsonProperty("schemaPattern") String schemaPattern) {
@@ -135,6 +201,80 @@ public interface Service {
ResultSetResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override SchemasRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.SchemasRequest)) {
+ throw new IllegalArgumentException(
+ "Expected SchemasRequest, but got" + genericMsg.getClass().getName());
+ }
+
+ final Requests.SchemasRequest msg = (Requests.SchemasRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String catalog = null;
+ if (ProtobufService.hasField(msg, desc, Requests.SchemasRequest.CATALOG_FIELD_NUMBER)) {
+ catalog = msg.getCatalog();
+ }
+
+ String schemaPattern = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.SchemasRequest.SCHEMA_PATTERN_FIELD_NUMBER)) {
+ schemaPattern = msg.getSchemaPattern();
+ }
+
+ return new SchemasRequest(catalog, schemaPattern);
+ }
+
+ @Override Requests.SchemasRequest serialize() {
+ Requests.SchemasRequest.Builder builder = Requests.SchemasRequest.newBuilder();
+ if (null != catalog) {
+ builder.setCatalog(catalog);
+ }
+ if (null != schemaPattern) {
+ builder.setSchemaPattern(schemaPattern);
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((catalog == null) ? 0 : catalog.hashCode());
+ result = prime * result + ((schemaPattern == null) ? 0 : schemaPattern.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof SchemasRequest) {
+ SchemasRequest other = (SchemasRequest) o;
+
+ if (null == catalog) {
+ // We're null, other is not
+ if (null != other.catalog) {
+ return false;
+ }
+ } else if (!catalog.equals(other.catalog)) {
+ return false;
+ }
+
+ if (null == schemaPattern) {
+ // We're null, they're not
+ if (null != other.schemaPattern) {
+ return false;
+ }
+ } else if (!catalog.equals(other.catalog)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -146,6 +286,13 @@ public interface Service {
public final String tableNamePattern;
public final List<String> typeList;
+ TablesRequest() {
+ catalog = null;
+ schemaPattern = null;
+ tableNamePattern = null;
+ typeList = null;
+ }
+
@JsonCreator
public TablesRequest(@JsonProperty("catalog") String catalog,
@JsonProperty("schemaPattern") String schemaPattern,
@@ -160,14 +307,141 @@ public interface Service {
@Override Response accept(Service service) {
return service.apply(this);
}
+
+ @Override Request deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.TablesRequest)) {
+ throw new IllegalArgumentException(
+ "Expected TablesRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.TablesRequest msg = (Requests.TablesRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String catalog = null;
+ if (ProtobufService.hasField(msg, desc, Requests.TablesRequest.CATALOG_FIELD_NUMBER)) {
+ catalog = msg.getCatalog();
+ }
+
+ String schemaPattern = null;
+ if (ProtobufService.hasField(msg, desc, Requests.TablesRequest.SCHEMA_PATTERN_FIELD_NUMBER)) {
+ schemaPattern = msg.getSchemaPattern();
+ }
+
+ String tableNamePattern = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.TablesRequest.TABLE_NAME_PATTERN_FIELD_NUMBER)) {
+ tableNamePattern = msg.getTableNamePattern();
+ }
+
+ return new TablesRequest(catalog, schemaPattern, tableNamePattern, msg.getTypeListList());
+ }
+
+ @Override Requests.TablesRequest serialize() {
+ Requests.TablesRequest.Builder builder = Requests.TablesRequest.newBuilder();
+
+ if (null != catalog) {
+ builder.setCatalog(catalog);
+ }
+ if (null != schemaPattern) {
+ builder.setSchemaPattern(schemaPattern);
+ }
+ if (null != tableNamePattern) {
+ builder.setTableNamePattern(tableNamePattern);
+ }
+ if (null != typeList) {
+ builder.addAllTypeList(typeList);
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((catalog == null) ? 0 : catalog.hashCode());
+ result = prime * result + ((schemaPattern == null) ? 0 : schemaPattern.hashCode());
+ result = prime * result + ((tableNamePattern == null) ? 0 : tableNamePattern.hashCode());
+ result = prime * result + ((typeList == null) ? 0 : typeList.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof TablesRequest) {
+ TablesRequest other = (TablesRequest) o;
+
+ if (null == catalog) {
+ if (null != catalog) {
+ return false;
+ }
+ } else if (!catalog.equals(other.catalog)) {
+ return false;
+ }
+
+ if (null == schemaPattern) {
+ if (null != other.schemaPattern) {
+ return false;
+ }
+ } else if (!schemaPattern.equals(other.schemaPattern)) {
+ return false;
+ }
+
+ if (null == tableNamePattern) {
+ if (null != other.tableNamePattern) {
+ return false;
+ }
+ } else if (!tableNamePattern.equals(other.tableNamePattern)) {
+ return false;
+ }
+
+ if (null == typeList) {
+ if (null != other.typeList) {
+ return false;
+ }
+ } else if (null == other.typeList || !typeList.equals(other.typeList)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
- /** Request for
- * {@link Meta#getTableTypes()}. */
+ /**
+ * Request for {@link Meta#getTableTypes()}.
+ */
class TableTypesRequest extends Request {
@Override ResultSetResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override TableTypesRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.TableTypesRequest)) {
+ throw new IllegalArgumentException(
+ "Expected TableTypesRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ return new TableTypesRequest();
+ }
+
+ @Override Requests.TableTypesRequest serialize() {
+ return Requests.TableTypesRequest.newBuilder().build();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ return o instanceof TableTypesRequest;
+ }
}
/** Request for
@@ -179,6 +453,13 @@ public interface Service {
public final String tableNamePattern;
public final String columnNamePattern;
+ ColumnsRequest() {
+ catalog = null;
+ schemaPattern = null;
+ tableNamePattern = null;
+ columnNamePattern = null;
+ }
+
@JsonCreator
public ColumnsRequest(@JsonProperty("catalog") String catalog,
@JsonProperty("schemaPattern") String schemaPattern,
@@ -193,6 +474,115 @@ public interface Service {
ResultSetResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override ColumnsRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.ColumnsRequest)) {
+ throw new IllegalArgumentException(
+ "Expected ColumnsRequest, but got" + genericMsg.getClass().getName());
+ }
+
+ final Requests.ColumnsRequest msg = (Requests.ColumnsRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String catalog = null;
+ if (ProtobufService.hasField(msg, desc, Requests.ColumnsRequest.CATALOG_FIELD_NUMBER)) {
+ catalog = msg.getCatalog();
+ }
+
+ String schemaPattern = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.ColumnsRequest.SCHEMA_PATTERN_FIELD_NUMBER)) {
+ schemaPattern = msg.getSchemaPattern();
+ }
+
+ String tableNamePattern = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.ColumnsRequest.TABLE_NAME_PATTERN_FIELD_NUMBER)) {
+ tableNamePattern = msg.getTableNamePattern();
+ }
+
+ String columnNamePattern = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.ColumnsRequest.COLUMN_NAME_PATTERN_FIELD_NUMBER)) {
+ columnNamePattern = msg.getColumnNamePattern();
+ }
+
+ return new ColumnsRequest(catalog, schemaPattern, tableNamePattern, columnNamePattern);
+ }
+
+ @Override Requests.ColumnsRequest serialize() {
+ Requests.ColumnsRequest.Builder builder = Requests.ColumnsRequest.newBuilder();
+
+ if (null != catalog) {
+ builder.setCatalog(catalog);
+ }
+ if (null != schemaPattern) {
+ builder.setSchemaPattern(schemaPattern);
+ }
+ if (null != tableNamePattern) {
+ builder.setTableNamePattern(tableNamePattern);
+ }
+ if (null != columnNamePattern) {
+ builder.setColumnNamePattern(columnNamePattern);
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((catalog == null) ? 0 : catalog.hashCode());
+ result = prime * result + ((columnNamePattern == null) ? 0 : columnNamePattern.hashCode());
+ result = prime * result + ((schemaPattern == null) ? 0 : schemaPattern.hashCode());
+ result = prime * result + ((tableNamePattern == null) ? 0 : tableNamePattern.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof ColumnsRequest) {
+ ColumnsRequest other = (ColumnsRequest) o;
+
+ if (null == catalog) {
+ if (null != other.catalog) {
+ return false;
+ }
+ } else if (!catalog.equals(other.catalog)) {
+ return false;
+ }
+
+ if (null == schemaPattern) {
+ if (null != other.schemaPattern) {
+ return false;
+ }
+ } else if (!schemaPattern.equals(other.schemaPattern)) {
+ return false;
+ }
+
+ if (null == tableNamePattern) {
+ if (null != other.tableNamePattern) {
+ return false;
+ }
+ } else if (!tableNamePattern.equals(other.tableNamePattern)) {
+ return false;
+ }
+
+ if (null == columnNamePattern) {
+ if (null != other.columnNamePattern) {
+ return false;
+ }
+ } else if (!columnNamePattern.equals(other.columnNamePattern)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -201,6 +591,30 @@ public interface Service {
@Override ResultSetResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override TypeInfoRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.TypeInfoRequest)) {
+ throw new IllegalArgumentException(
+ "Expected TypeInfoRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ return new TypeInfoRequest();
+ }
+
+ @Override Requests.TypeInfoRequest serialize() {
+ return Requests.TypeInfoRequest.newBuilder().build();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ return o instanceof TypeInfoRequest;
+ }
}
/** Response that contains a result set.
@@ -223,6 +637,15 @@ public interface Service {
public final Meta.Frame firstFrame;
public final long updateCount;
+ ResultSetResponse() {
+ connectionId = null;
+ statementId = 0;
+ ownStatement = false;
+ signature = null;
+ firstFrame = null;
+ updateCount = 0;
+ }
+
@JsonCreator
public ResultSetResponse(
@JsonProperty("connectionId") String connectionId,
@@ -238,6 +661,109 @@ public interface Service {
this.firstFrame = firstFrame;
this.updateCount = updateCount;
}
+
+ @Override ResultSetResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.ResultSetResponse)) {
+ throw new IllegalArgumentException(
+ "Expected ResultSetResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ return fromProto((Responses.ResultSetResponse) genericMsg);
+ }
+
+ static ResultSetResponse fromProto(Responses.ResultSetResponse msg) {
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Responses.ResultSetResponse.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ Meta.Signature signature = null;
+ if (ProtobufService.hasField(msg, desc, Responses.ResultSetResponse.SIGNATURE_FIELD_NUMBER)) {
+ signature = Meta.Signature.fromProto(msg.getSignature());
+ }
+
+ Meta.Frame frame = null;
+ if (ProtobufService.hasField(msg, desc,
+ Responses.ResultSetResponse.FIRST_FRAME_FIELD_NUMBER)) {
+ frame = Meta.Frame.fromProto(msg.getFirstFrame());
+ }
+
+ return new ResultSetResponse(connectionId, msg.getStatementId(), msg.getOwnStatement(),
+ signature, frame, msg.getUpdateCount());
+ }
+
+ @Override Responses.ResultSetResponse serialize() {
+ Responses.ResultSetResponse.Builder builder = Responses.ResultSetResponse.newBuilder();
+
+ builder.setStatementId(statementId).setOwnStatement(ownStatement).setUpdateCount(updateCount);
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ if (null != signature) {
+ builder.setSignature(signature.toProto());
+ }
+
+ if (null != firstFrame) {
+ builder.setFirstFrame(firstFrame.toProto());
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ result = prime * result + ((firstFrame == null) ? 0 : firstFrame.hashCode());
+ result = prime * result + (ownStatement ? 1231 : 1237);
+ result = prime * result + ((signature == null) ? 0 : signature.hashCode());
+ result = prime * result + statementId;
+ result = prime * result + (int) (updateCount ^ (updateCount >>> 32));
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof ResultSetResponse) {
+ ResultSetResponse other = (ResultSetResponse) o;
+
+ if (connectionId == null) {
+ if (other.connectionId != null) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ if (firstFrame == null) {
+ if (other.firstFrame != null) {
+ return false;
+ }
+ } else if (!firstFrame.equals(other.firstFrame)) {
+ return false;
+ }
+
+ if (signature == null) {
+ if (other.signature != null) {
+ return false;
+ }
+ } else if (!signature.equals(other.signature)) {
+ return false;
+ }
+
+ return ownStatement == other.ownStatement && statementId == other.statementId
+ && updateCount == other.updateCount;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -248,6 +774,13 @@ public interface Service {
public final long maxRowCount;
public final int statementId;
+ PrepareAndExecuteRequest() {
+ connectionId = null;
+ sql = null;
+ maxRowCount = 0;
+ statementId = 0;
+ }
+
@JsonCreator
public PrepareAndExecuteRequest(
@JsonProperty("connectionId") String connectionId,
@@ -263,6 +796,85 @@ public interface Service {
@Override ExecuteResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override PrepareAndExecuteRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.PrepareAndExecuteRequest)) {
+ throw new IllegalArgumentException(
+ "Expected PrepareAndExecuteRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.PrepareAndExecuteRequest msg = (Requests.PrepareAndExecuteRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.PrepareAndExecuteRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ String sql = null;
+ if (ProtobufService.hasField(msg, desc, Requests.PrepareAndExecuteRequest.SQL_FIELD_NUMBER)) {
+ sql = msg.getSql();
+ }
+
+ return new PrepareAndExecuteRequest(connectionId, msg.getStatementId(), sql,
+ msg.getMaxRowCount());
+ }
+
+ @Override Requests.PrepareAndExecuteRequest serialize() {
+ Requests.PrepareAndExecuteRequest.Builder builder = Requests.PrepareAndExecuteRequest
+ .newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+ if (null != sql) {
+ builder.setSql(sql);
+ }
+ builder.setStatementId(statementId);
+ builder.setMaxRowCount(maxRowCount);
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ result = prime * result + (int) (maxRowCount ^ (maxRowCount >>> 32));
+ result = prime * result + ((sql == null) ? 0 : sql.hashCode());
+ result = prime * result + statementId;
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof PrepareAndExecuteRequest) {
+ PrepareAndExecuteRequest other = (PrepareAndExecuteRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ if (null == sql) {
+ if (null != other.sql) {
+ return false;
+ }
+ } else if (!sql.equals(other.sql)) {
+ return false;
+ }
+
+ return statementId == other.statementId && maxRowCount == other.maxRowCount;
+ }
+
+ return false;
+ }
}
/** Response to a
@@ -270,11 +882,72 @@ public interface Service {
class ExecuteResponse extends Response {
public final List<ResultSetResponse> results;
+ ExecuteResponse() {
+ results = null;
+ }
+
@JsonCreator
public ExecuteResponse(
@JsonProperty("resultSets") List<ResultSetResponse> results) {
this.results = results;
}
+
+ @Override ExecuteResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.ExecuteResponse)) {
+ throw new IllegalArgumentException(
+ "Expected ExecuteResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ Responses.ExecuteResponse msg = (Responses.ExecuteResponse) genericMsg;
+
+ List<Responses.ResultSetResponse> msgResults = msg.getResultsList();
+ List<ResultSetResponse> copiedResults = new ArrayList<>(msgResults.size());
+
+ for (Responses.ResultSetResponse msgResult : msgResults) {
+ copiedResults.add(ResultSetResponse.fromProto(msgResult));
+ }
+
+ return new ExecuteResponse(copiedResults);
+ }
+
+ @Override Responses.ExecuteResponse serialize() {
+ Responses.ExecuteResponse.Builder builder = Responses.ExecuteResponse.newBuilder();
+
+ for (ResultSetResponse result : results) {
+ builder.addResults(result.serialize());
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ if (null == results) {
+ return 0;
+ }
+
+ return results.hashCode();
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof ExecuteResponse) {
+ ExecuteResponse other = (ExecuteResponse) o;
+
+ if (null == results) {
+ if (null != other.results) {
+ return false;
+ }
+ } else if (!results.equals(other.results)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -284,6 +957,12 @@ public interface Service {
public final String sql;
public final long maxRowCount;
+ PrepareRequest() {
+ connectionId = null;
+ sql = null;
+ maxRowCount = 0;
+ }
+
@JsonCreator
public PrepareRequest(
@JsonProperty("connectionId") String connectionId,
@@ -297,6 +976,80 @@ public interface Service {
@Override PrepareResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override PrepareRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.PrepareRequest)) {
+ throw new IllegalArgumentException(
+ "Expected PrepareRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.PrepareRequest msg = (Requests.PrepareRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc, Requests.PrepareRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ String sql = null;
+ if (ProtobufService.hasField(msg, desc, Requests.PrepareRequest.SQL_FIELD_NUMBER)) {
+ sql = msg.getSql();
+ }
+
+ return new PrepareRequest(connectionId, sql, msg.getMaxRowCount());
+ }
+
+ @Override Requests.PrepareRequest serialize() {
+ Requests.PrepareRequest.Builder builder = Requests.PrepareRequest.newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ if (null != sql) {
+ builder.setSql(sql);
+ }
+
+ return builder.setMaxRowCount(maxRowCount).build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ result = prime * result + (int) (maxRowCount ^ (maxRowCount >>> 32));
+ result = prime * result + ((sql == null) ? 0 : sql.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof PrepareRequest) {
+ PrepareRequest other = (PrepareRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ if (null == sql) {
+ if (null != other.sql) {
+ return false;
+ }
+ } else if (!sql.equals(other.sql)) {
+ return false;
+ }
+
+ return maxRowCount == other.maxRowCount;
+ }
+
+ return false;
+ }
}
/** Response from
@@ -304,11 +1057,64 @@ public interface Service {
class PrepareResponse extends Response {
public final Meta.StatementHandle statement;
+ PrepareResponse() {
+ statement = null;
+ }
+
@JsonCreator
public PrepareResponse(
@JsonProperty("statement") Meta.StatementHandle statement) {
this.statement = statement;
}
+
+ @Override PrepareResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.PrepareResponse)) {
+ throw new IllegalArgumentException(
+ "Expected PrepareResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ Responses.PrepareResponse msg = (Responses.PrepareResponse) genericMsg;
+
+ return new PrepareResponse(Meta.StatementHandle.fromProto(msg.getStatement()));
+ }
+
+ @Override Responses.PrepareResponse serialize() {
+ Responses.PrepareResponse.Builder builder = Responses.PrepareResponse.newBuilder();
+
+ if (null != statement) {
+ builder.setStatement(statement.toProto());
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((statement == null) ? 0 : statement.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof PrepareResponse) {
+ PrepareResponse other = (PrepareResponse) o;
+
+ if (statement == null) {
+ if (other.statement != null) {
+ return false;
+ }
+ } else if (!statement.equals(other.statement)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -324,6 +1130,14 @@ public interface Service {
* null. */
public final List<TypedValue> parameterValues;
+ FetchRequest() {
+ connectionId = null;
+ statementId = 0;
+ offset = 0;
+ fetchMaxRowCount = 0;
+ parameterValues = null;
+ }
+
@JsonCreator
public FetchRequest(
@JsonProperty("connectionId") String connectionId,
@@ -341,6 +1155,99 @@ public interface Service {
@Override FetchResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override FetchRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.FetchRequest)) {
+ throw new IllegalArgumentException(
+ "Expected FetchRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.FetchRequest msg = (Requests.FetchRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ // Cannot determine if a value was set for a repeated field. Must use an extra boolean
+ // parameter to distinguish an empty list and a null list of ParameterValues.
+ List<TypedValue> values = null;
+ if (msg.getHasParameterValues()) {
+ values = new ArrayList<>(msg.getParameterValuesCount());
+ for (Common.TypedValue valueProto : msg.getParameterValuesList()) {
+ values.add(TypedValue.fromProto(valueProto));
+ }
+ }
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc, Requests.FetchRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ return new FetchRequest(connectionId, msg.getStatementId(), values, msg.getOffset(),
+ msg.getFetchMaxRowCount());
+ }
+
+ @Override Requests.FetchRequest serialize() {
+ Requests.FetchRequest.Builder builder = Requests.FetchRequest.newBuilder();
+
+ if (null != parameterValues) {
+ builder.setHasParameterValues(true);
+ for (TypedValue paramValue : parameterValues) {
+ builder.addParameterValues(paramValue.toProto());
+ }
+ } else {
+ builder.setHasParameterValues(false);
+ }
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ builder.setStatementId(statementId);
+ builder.setOffset(offset);
+ builder.setFetchMaxRowCount(fetchMaxRowCount);
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ result = prime * result + fetchMaxRowCount;
+ result = prime * result + (int) (offset ^ (offset >>> 32));
+ result = prime * result + ((parameterValues == null) ? 0 : parameterValues.hashCode());
+ result = prime * result + statementId;
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof FetchRequest) {
+ FetchRequest other = (FetchRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else {
+ if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+ }
+
+ if (null == parameterValues) {
+ if (null != other.parameterValues) {
+ return false;
+ }
+ } else if (!parameterValues.equals(other.parameterValues)) {
+ return false;
+ }
+
+ return offset == other.offset && fetchMaxRowCount == other.fetchMaxRowCount;
+ }
+
+ return false;
+ }
}
/** Response from
@@ -348,10 +1255,63 @@ public interface Service {
class FetchResponse extends Response {
public final Meta.Frame frame;
+ FetchResponse() {
+ frame = null;
+ }
+
@JsonCreator
public FetchResponse(@JsonProperty("frame") Meta.Frame frame) {
this.frame = frame;
}
+
+ @Override FetchResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.FetchResponse)) {
+ throw new IllegalArgumentException(
+ "Expected FetchResponse, but got" + genericMsg.getClass().getName());
+ }
+
+ Responses.FetchResponse msg = (Responses.FetchResponse) genericMsg;
+
+ return new FetchResponse(Meta.Frame.fromProto(msg.getFrame()));
+ }
+
+ @Override Responses.FetchResponse serialize() {
+ Responses.FetchResponse.Builder builder = Responses.FetchResponse.newBuilder();
+
+ if (null != frame) {
+ builder.setFrame(frame.toProto());
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((frame == null) ? 0 : frame.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof FetchResponse) {
+ FetchResponse other = (FetchResponse) o;
+
+ if (frame == null) {
+ if (other.frame != null) {
+ return false;
+ }
+ } else if (!frame.equals(other.frame)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -359,6 +1319,10 @@ public interface Service {
class CreateStatementRequest extends Request {
public final String connectionId;
+ CreateStatementRequest() {
+ connectionId = null;
+ }
+
@JsonCreator
public CreateStatementRequest(
@JsonProperty("signature") String connectionId) {
@@ -368,6 +1332,63 @@ public interface Service {
@Override CreateStatementResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override CreateStatementRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.CreateStatementRequest)) {
+ throw new IllegalArgumentException(
+ "Expected CreateStatementRequest, but got" + genericMsg.getClass().getName());
+ }
+
+ final Requests.CreateStatementRequest msg = (Requests.CreateStatementRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.CreateStatementRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ return new CreateStatementRequest(connectionId);
+ }
+
+ @Override Requests.CreateStatementRequest serialize() {
+ Requests.CreateStatementRequest.Builder builder = Requests.CreateStatementRequest
+ .newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof CreateStatementRequest) {
+ CreateStatementRequest other = (CreateStatementRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Response from
@@ -376,6 +1397,11 @@ public interface Service {
public final String connectionId;
public final int statementId;
+ CreateStatementResponse() {
+ connectionId = null;
+ statementId = 0;
+ }
+
@JsonCreator
public CreateStatementResponse(
@JsonProperty("connectionId") String connectionId,
@@ -383,6 +1409,66 @@ public interface Service {
this.connectionId = connectionId;
this.statementId = statementId;
}
+
+ @Override CreateStatementResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.CreateStatementResponse)) {
+ throw new IllegalArgumentException(
+ "Expected CreateStatementResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ final Responses.CreateStatementResponse msg = (Responses.CreateStatementResponse) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Responses.CreateStatementResponse.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ return new CreateStatementResponse(connectionId, msg.getStatementId());
+ }
+
+ @Override Responses.CreateStatementResponse serialize() {
+ Responses.CreateStatementResponse.Builder builder = Responses.CreateStatementResponse
+ .newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ builder.setStatementId(statementId);
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ result = prime * result + statementId;
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof CreateStatementResponse) {
+ CreateStatementResponse other = (CreateStatementResponse) o;
+
+ if (connectionId == null) {
+ if (other.connectionId != null) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ return statementId == other.statementId;
+ }
+
+ return false;
+ }
}
/** Request for
@@ -391,6 +1477,11 @@ public interface Service {
public final String connectionId;
public final int statementId;
+ CloseStatementRequest() {
+ connectionId = null;
+ statementId = 0;
+ }
+
@JsonCreator
public CloseStatementRequest(
@JsonProperty("connectionId") String connectionId,
@@ -402,6 +1493,63 @@ public interface Service {
@Override CloseStatementResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override CloseStatementRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.CloseStatementRequest)) {
+ throw new IllegalArgumentException(
+ "Expected CloseStatementRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.CloseStatementRequest msg = (Requests.CloseStatementRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.CloseStatementRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ return new CloseStatementRequest(connectionId, msg.getStatementId());
+ }
+
+ @Override Requests.CloseStatementRequest serialize() {
+ Requests.CloseStatementRequest.Builder builder = Requests.CloseStatementRequest.newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ return builder.setStatementId(statementId).build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ result = prime * result + statementId;
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof CloseStatementRequest) {
+ CloseStatementRequest other = (CloseStatementRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ return statementId == other.statementId;
+ }
+
+ return false;
+ }
}
/** Response from
@@ -409,6 +1557,30 @@ public interface Service {
class CloseStatementResponse extends Response {
@JsonCreator
public CloseStatementResponse() {}
+
+ @Override CloseStatementResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.CloseStatementResponse)) {
+ throw new IllegalArgumentException(
+ "Expected CloseStatementResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ return new CloseStatementResponse();
+ }
+
+ @Override Responses.CloseStatementResponse serialize() {
+ return Responses.CloseStatementResponse.newBuilder().build();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ return o instanceof CloseStatementResponse;
+ }
}
/** Request for
@@ -416,6 +1588,10 @@ public interface Service {
class CloseConnectionRequest extends Request {
public final String connectionId;
+ CloseConnectionRequest() {
+ connectionId = null;
+ }
+
@JsonCreator
public CloseConnectionRequest(
@JsonProperty("connectionId") String connectionId) {
@@ -425,6 +1601,63 @@ public interface Service {
@Override CloseConnectionResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override CloseConnectionRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.CloseConnectionRequest)) {
+ throw new IllegalArgumentException(
+ "Expected CloseConnectionRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.CloseConnectionRequest msg = (Requests.CloseConnectionRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.CloseConnectionRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ return new CloseConnectionRequest(connectionId);
+ }
+
+ @Override Requests.CloseConnectionRequest serialize() {
+ Requests.CloseConnectionRequest.Builder builder = Requests.CloseConnectionRequest
+ .newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof CloseConnectionRequest) {
+ CloseConnectionRequest other = (CloseConnectionRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Response from
@@ -432,6 +1665,30 @@ public interface Service {
class CloseConnectionResponse extends Response {
@JsonCreator
public CloseConnectionResponse() {}
+
+ @Override CloseConnectionResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.CloseConnectionResponse)) {
+ throw new IllegalArgumentException(
+ "Expected CloseConnectionResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ return new CloseConnectionResponse();
+ }
+
+ @Override Responses.CloseConnectionResponse serialize() {
+ return Responses.CloseConnectionResponse.newBuilder().build();
+ }
+
+ @Override public int hashCode() {
+ return 0;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ return o instanceof CloseConnectionResponse;
+ }
}
/** Request for {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */
@@ -439,6 +1696,11 @@ public interface Service {
public final String connectionId;
public final Meta.ConnectionProperties connProps;
+ ConnectionSyncRequest() {
+ connectionId = null;
+ connProps = null;
+ }
+
@JsonCreator
public ConnectionSyncRequest(
@JsonProperty("connectionId") String connectionId,
@@ -450,6 +1712,81 @@ public interface Service {
@Override ConnectionSyncResponse accept(Service service) {
return service.apply(this);
}
+
+ @Override ConnectionSyncRequest deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Requests.ConnectionSyncRequest)) {
+ throw new IllegalArgumentException(
+ "Expected ConnectionSyncRequest, but got " + genericMsg.getClass().getName());
+ }
+
+ final Requests.ConnectionSyncRequest msg = (Requests.ConnectionSyncRequest) genericMsg;
+ final Descriptor desc = msg.getDescriptorForType();
+
+ String connectionId = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.ConnectionSyncRequest.CONNECTION_ID_FIELD_NUMBER)) {
+ connectionId = msg.getConnectionId();
+ }
+
+ Meta.ConnectionProperties connProps = null;
+ if (ProtobufService.hasField(msg, desc,
+ Requests.ConnectionSyncRequest.CONN_PROPS_FIELD_NUMBER)) {
+ connProps = ConnectionPropertiesImpl.fromProto(msg.getConnProps());
+ }
+
+ return new ConnectionSyncRequest(connectionId, connProps);
+ }
+
+ @Override Requests.ConnectionSyncRequest serialize() {
+ Requests.ConnectionSyncRequest.Builder builder = Requests.ConnectionSyncRequest.newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ if (null != connProps) {
+ builder.setConnProps(connProps.toProto());
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((connProps == null) ? 0 : connProps.hashCode());
+ result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof ConnectionSyncRequest) {
+ ConnectionSyncRequest other = (ConnectionSyncRequest) o;
+
+ if (null == connectionId) {
+ if (null != other.connectionId) {
+ return false;
+ }
+ } else if (!connectionId.equals(other.connectionId)) {
+ return false;
+ }
+
+ if (null == connProps) {
+ if (null != other.connProps) {
+ return false;
+ }
+ } else if (!connProps.equals(other.connProps)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Response for
@@ -457,10 +1794,65 @@ public interface Service {
class ConnectionSyncResponse extends Response {
public final Meta.ConnectionProperties connProps;
+ ConnectionSyncResponse() {
+ connProps = null;
+ }
+
@JsonCreator
public ConnectionSyncResponse(@JsonProperty("connProps") Meta.ConnectionProperties connProps) {
this.connProps = connProps;
}
+
+ @Override ConnectionSyncResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.ConnectionSyncResponse)) {
+ throw new IllegalArgumentException(
+ "Expected ConnectionSyncResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ Responses.ConnectionSyncResponse msg = (Responses.ConnectionSyncResponse) genericMsg;
+
+ return new ConnectionSyncResponse(ConnectionPropertiesImpl.fromProto(msg.getConnProps()));
+ }
+
+ @Override Responses.ConnectionSyncResponse serialize() {
+ Responses.ConnectionSyncResponse.Builder builder = Responses.ConnectionSyncResponse
+ .newBuilder();
+
+ if (null != connProps) {
+ builder.setConnProps(connProps.toProto());
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ if (null == connProps) {
+ return 0;
+ }
+
+ return connProps.hashCode();
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof ConnectionSyncResponse) {
+ ConnectionSyncResponse other = (ConnectionSyncResponse) o;
+
+ if (null == connProps) {
+ if (null != other.connProps) {
+ return false;
+ }
+ } else if (!connProps.equals(other.connProps)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
/** Response for
@@ -468,10 +1860,132 @@ public interface Service {
class DatabasePropertyResponse extends Response {
public final Map<Meta.DatabaseProperty, Object> map;
+ DatabasePropertyResponse() {
+ map = null;
+ }
+
@JsonCreator
public DatabasePropertyResponse(@JsonProperty("map") Map<Meta.DatabaseProperty, Object> map) {
this.map = map;
}
+
+ @Override DatabasePropertyResponse deserialize(Message genericMsg) {
+ if (!(genericMsg instanceof Responses.DatabasePropertyResponse)) {
+ throw new IllegalArgumentException(
+ "Expected DatabasePropertyResponse, but got " + genericMsg.getClass().getName());
+ }
+
+ Responses.DatabasePropertyResponse msg = (Responses.DatabasePropertyResponse) genericMsg;
+
+ HashMap<Meta.DatabaseProperty, Object> properties = new HashMap<>();
+ for (Responses.DatabasePropertyElement property : msg.getPropsList()) {
+ final Meta.DatabaseProperty dbProp = Meta.DatabaseProperty.fromProto(property.getKey());
+ final Common.TypedValue value = property.getValue();
+
+ Object obj;
+ switch (dbProp) {
+ // Just need to keep parity with the exposed values on DatabaseProperty
+ case GET_NUMERIC_FUNCTIONS:
+ case GET_STRING_FUNCTIONS:
+ case GET_SYSTEM_FUNCTIONS:
+ case GET_TIME_DATE_FUNCTIONS:
+ case GET_S_Q_L_KEYWORDS:
+ // String
+ if (Common.Rep.STRING != value.getType()) {
+ throw new IllegalArgumentException("Expected STRING, but got " + value.getType());
+ }
+
+ obj = value.getStringValue();
+ break;
+ case GET_DEFAULT_TRANSACTION_ISOLATION:
+ // int
+ if (Common.Rep.INTEGER != value.getType()) {
+ throw new IllegalArgumentException("Expected INTEGER, but got " + value.getType());
+ }
+
+ obj = Integer.valueOf((int) value.getNumberValue());
+ break;
+ default:
+ throw new RuntimeException("Unhandled DatabaseProperty");
+ }
+
+ properties.put(dbProp, obj);
+ }
+
+ return new DatabasePropertyResponse(properties);
+ }
+
+ @Override Responses.DatabasePropertyResponse serialize() {
+ Responses.DatabasePropertyResponse.Builder builder = Responses.DatabasePropertyResponse
+ .newBuilder();
+
+ if (null != map) {
+ for (Entry<Meta.DatabaseProperty, Object> entry : map.entrySet()) {
+ Object obj = entry.getValue();
+
+ Common.TypedValue.Builder valueBuilder = Common.TypedValue.newBuilder();
+ switch (entry.getKey()) {
+ // Just need to keep parity with the exposed values on DatabaseProperty
+ case GET_NUMERIC_FUNCTIONS:
+ case GET_STRING_FUNCTIONS:
+ case GET_SYSTEM_FUNCTIONS:
+ case GET_TIME_DATE_FUNCTIONS:
+ case GET_S_Q_L_KEYWORDS:
+ // String
+ if (!(obj instanceof String)) {
+ throw new RuntimeException("Expected a String, but got " + obj.getClass());
+ }
+
+ valueBuilder.setType(Common.Rep.STRING).setStringValue((String) obj);
+ break;
+ case GET_DEFAULT_TRANSACTION_ISOLATION:
+ // int
+ if (!(obj instanceof Integer)) {
+ throw new RuntimeException("Expected an Integer, but got " + obj.getClass());
+ }
+
+ valueBuilder.setType(Common.Rep.INTEGER).setNumberValue(((Integer) obj).longValue());
+ break;
+ default:
+ throw new RuntimeException("Unhandled DatabaseProperty");
+ }
+
+ builder.addProps(Responses.DatabasePropertyElement.newBuilder()
+ .setKey(entry.getKey().toProto()).setValue(valueBuilder.build()));
+ }
+ }
+
+ return builder.build();
+ }
+
+ @Override public int hashCode() {
+ if (null == map) {
+ return 0;
+ }
+
+ return map.hashCode();
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof DatabasePropertyResponse) {
+ DatabasePropertyResponse other = (DatabasePropertyResponse) o;
+
+ if (null == map) {
+ if (null != other.map) {
+ return false;
+ }
+ } else if (!map.equals(other.map)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java b/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
index d12fc40..5c80816 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
@@ -17,6 +17,7 @@
package org.apache.calcite.avatica.remote;
import org.apache.calcite.avatica.ColumnMetaData;
+import org.apache.calcite.avatica.proto.Common;
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.avatica.util.DateTimeUtils;
@@ -329,6 +330,203 @@ public class TypedValue {
}
return list;
}
+
+ public Common.TypedValue toProto() {
+ final Common.TypedValue.Builder builder = Common.TypedValue.newBuilder();
+
+ Common.Rep protoRep = type.toProto();
+ builder.setType(protoRep);
+
+ // Serialize the type into the protobuf
+ switch (protoRep) {
+ case BOOLEAN:
+ case PRIMITIVE_BOOLEAN:
+ builder.setBoolValue((boolean) value);
+ break;
+ case BYTE_STRING:
+ case STRING:
+ builder.setStringValue((String) value);
+ break;
+ case PRIMITIVE_CHAR:
+ case CHARACTER:
+ builder.setStringValue(Character.toString((char) value));
+ break;
+ case BYTE:
+ case PRIMITIVE_BYTE:
+ builder.setNumberValue(Byte.valueOf((byte) value).longValue());
+ break;
+ case DOUBLE:
+ case PRIMITIVE_DOUBLE:
+ builder.setDoubleValue((double) value);
+ break;
+ case FLOAT:
+ case PRIMITIVE_FLOAT:
+ builder.setNumberValue(Float.floatToIntBits((float) value));
+ break;
+ case INTEGER:
+ case PRIMITIVE_INT:
+ builder.setNumberValue(Integer.valueOf((int) value).longValue());
+ break;
+ case PRIMITIVE_SHORT:
+ case SHORT:
+ builder.setNumberValue(Short.valueOf((short) value).longValue());
+ break;
+ case LONG:
+ case PRIMITIVE_LONG:
+ builder.setNumberValue((long) value);
+ break;
+ case JAVA_SQL_DATE:
+ case JAVA_SQL_TIME:
+ // Persisted as integers
+ builder.setNumberValue(Integer.valueOf((int) value).longValue());
+ break;
+ case JAVA_SQL_TIMESTAMP:
+ case JAVA_UTIL_DATE:
+ // Persisted as longs
+ builder.setNumberValue((long) value);
+ break;
+ case BIG_INTEGER:
+ byte[] bytes = ((BigInteger) value).toByteArray();
+ builder.setBytesValues(com.google.protobuf.ByteString.copyFrom(bytes));
+ break;
+ case BIG_DECIMAL:
+ final BigDecimal bigDecimal = (BigDecimal) value;
+ final int scale = bigDecimal.scale();
+ final BigInteger bigInt = bigDecimal.toBigInteger();
+ builder.setBytesValues(com.google.protobuf.ByteString.copyFrom(bigInt.toByteArray()))
+ .setNumberValue(scale);
+ break;
+ case NUMBER:
+ builder.setNumberValue(((Number) value).longValue());
+ break;
+ case OBJECT:
+ if (null == value) {
+ // We can persist a null value through easily
+ builder.setNull(true);
+ break;
+ }
+ // Intentional fall-through to RTE because we can't serialize something we have no type
+ // insight into.
+ case UNRECOGNIZED:
+ // Fail?
+ throw new RuntimeException("Unhandled value: " + protoRep + " " + value.getClass());
+ default:
+ // Fail?
+ throw new RuntimeException("Unknown serialized type: " + protoRep);
+ }
+
+ return builder.build();
+ }
+
+ public static TypedValue fromProto(Common.TypedValue proto) {
+ ColumnMetaData.Rep rep = ColumnMetaData.Rep.fromProto(proto.getType());
+
+ Object value = null;
+
+ // Deserialize the value again
+ switch (proto.getType()) {
+ case BOOLEAN:
+ case PRIMITIVE_BOOLEAN:
+ value = proto.getBoolValue();
+ break;
+ case BYTE_STRING:
+ case STRING:
+ value = proto.getStringValue();
+ break;
+ case PRIMITIVE_CHAR:
+ case CHARACTER:
+ value = proto.getStringValue().charAt(0);
+ break;
+ case BYTE:
+ case PRIMITIVE_BYTE:
+ value = Long.valueOf(proto.getNumberValue()).byteValue();
+ break;
+ case DOUBLE:
+ case PRIMITIVE_DOUBLE:
+ value = proto.getDoubleValue();
+ break;
+ case FLOAT:
+ case PRIMITIVE_FLOAT:
+ value = Float.intBitsToFloat((int) proto.getNumberValue());
+ break;
+ case INTEGER:
+ case PRIMITIVE_INT:
+ value = Long.valueOf(proto.getNumberValue()).intValue();
+ break;
+ case PRIMITIVE_SHORT:
+ case SHORT:
+ value = Long.valueOf(proto.getNumberValue()).shortValue();
+ break;
+ case LONG:
+ case PRIMITIVE_LONG:
+ value = Long.valueOf(proto.getNumberValue());
+ break;
+ case JAVA_SQL_DATE:
+ case JAVA_SQL_TIME:
+ value = Long.valueOf(proto.getNumberValue()).intValue();
+ break;
+ case JAVA_SQL_TIMESTAMP:
+ case JAVA_UTIL_DATE:
+ value = proto.getNumberValue();
+ break;
+ case BIG_INTEGER:
+ value = new BigInteger(proto.getBytesValues().toByteArray());
+ break;
+ case BIG_DECIMAL:
+ BigInteger bigInt = new BigInteger(proto.getBytesValues().toByteArray());
+ value = new BigDecimal(bigInt, (int) proto.getNumberValue());
+ break;
+ case NUMBER:
+ value = Long.valueOf(proto.getNumberValue());
+ break;
+ case OBJECT:
+ if (proto.getNull()) {
+ value = null;
+ break;
+ }
+ // Intentional fall through to RTE. If we sent an object over the wire, it could only
+ // possibly be null (at this point). Anything else has to be an error.
+ case UNRECOGNIZED:
+ // Fail?
+ throw new RuntimeException("Unhandled type: " + proto.getType());
+ default:
+ // Fail?
+ throw new RuntimeException("Unknown type: " + proto.getType());
+ }
+
+ return new TypedValue(rep, value);
+ }
+
+ @Override public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((type == null) ? 0 : type.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof TypedValue) {
+ TypedValue other = (TypedValue) o;
+
+ if (type != other.type) {
+ return false;
+ }
+
+ if (null == value) {
+ if (null != other.value) {
+ return false;
+ }
+ }
+
+ return value.equals(other.value);
+ }
+
+ return false;
+ }
}
// End TypedValue.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
----------------------------------------------------------------------
diff --git a/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java b/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
index 9786c7a..6d862d3 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/util/AbstractCursor.java
@@ -765,6 +765,13 @@ public abstract class AbstractCursor implements Cursor {
}
@Override public byte[] getBytes() {
+ // JSON sends this as a base64-enc string, protobuf can do binary.
+ Object obj = getObject();
+ if (obj instanceof byte[]) {
+ // If we already have bytes, just send them back.
+ return (byte[]) obj;
+ }
+
final String string = getString();
if (string == null) {
return null;
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/protobuf/common.proto
----------------------------------------------------------------------
diff --git a/avatica/src/main/protobuf/common.proto b/avatica/src/main/protobuf/common.proto
new file mode 100644
index 0000000..1c81049
--- /dev/null
+++ b/avatica/src/main/protobuf/common.proto
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+option java_package = "org.apache.calcite.avatica.proto";
+
+// Details about a connection
+message ConnectionProperties {
+ bool is_dirty = 1;
+ bool auto_commit = 2;
+ bool has_auto_commit = 7; // field is a Boolean, need to discern null and default value
+ bool read_only = 3;
+ bool has_read_only = 8; // field is a Boolean, need to discern null and default value
+ uint32 transaction_isolation = 4;
+ string catalog = 5;
+ string schema = 6;
+}
+
+// Statement handle
+message StatementHandle {
+ string connection_id = 1;
+ uint32 id = 2;
+ Signature signature = 3;
+}
+
+// Results of preparing a statement
+message Signature {
+ repeated ColumnMetaData columns = 1;
+ string sql = 2;
+ repeated AvaticaParameter parameters = 3;
+ CursorFactory cursor_factory = 4;
+}
+
+message ColumnMetaData {
+ uint32 ordinal = 1;
+ bool auto_increment = 2;
+ bool case_sensitive = 3;
+ bool searchable = 4;
+ bool currency = 5;
+ uint32 nullable = 6;
+ bool signed = 7;
+ uint32 display_size = 8;
+ string label = 9;
+ string column_name = 10;
+ string schema_name = 11;
+ uint32 precision = 12;
+ uint32 scale = 13;
+ string table_name = 14;
+ string catalog_name = 15;
+ bool read_only = 16;
+ bool writable = 17;
+ bool definitely_writable = 18;
+ string column_class_name = 19;
+ AvaticaType type = 20;
+}
+
+enum Rep {
+ PRIMITIVE_BOOLEAN = 0;
+ PRIMITIVE_BYTE = 1;
+ PRIMITIVE_CHAR = 2;
+ PRIMITIVE_SHORT = 3;
+ PRIMITIVE_INT = 4;
+ PRIMITIVE_LONG = 5;
+ PRIMITIVE_FLOAT = 6;
+ PRIMITIVE_DOUBLE = 7;
+ BOOLEAN = 8;
+ BYTE = 9;
+ CHARACTER = 10;
+ SHORT = 11;
+ INTEGER = 12;
+ LONG = 13;
+ FLOAT = 14;
+ DOUBLE = 15;
+ BIG_INTEGER = 25;
+ BIG_DECIMAL = 26;
+ JAVA_SQL_TIME = 16;
+ JAVA_SQL_TIMESTAMP = 17;
+ JAVA_SQL_DATE = 18;
+ JAVA_UTIL_DATE = 19;
+ BYTE_STRING = 20;
+ STRING = 21;
+ NUMBER = 22;
+ OBJECT = 23;
+ NULL = 24;
+}
+
+// Base class for a column type
+message AvaticaType {
+ uint32 id = 1;
+ string name = 2;
+ Rep rep = 3;
+
+ repeated ColumnMetaData columns = 4; // Only present when name = STRUCT
+ AvaticaType component = 5; // Only present when name = ARRAY
+}
+
+// Metadata for a parameter
+message AvaticaParameter {
+ bool signed = 1;
+ uint32 precision = 2;
+ uint32 scale = 3;
+ uint32 parameter_type = 4;
+ string type_name = 5;
+ string class_name = 6;
+ string name = 7;
+}
+
+// Information necessary to convert an Iterable into a Calcite Cursor
+message CursorFactory {
+ enum Style {
+ OBJECT = 0;
+ RECORD = 1;
+ RECORD_PROJECTION = 2;
+ ARRAY = 3;
+ LIST = 4;
+ MAP = 5;
+ }
+
+ Style style = 1;
+ string class_name = 2;
+ repeated string field_names = 3;
+}
+
+// A collection of rows
+message Frame {
+ uint64 offset = 1;
+ bool done = 2;
+ repeated Row rows = 3;
+}
+
+// A row is a collection of values
+message Row {
+ repeated TypedValue value = 1;
+}
+
+// Database property, list of functions the database provides for a certain operation
+message DatabaseProperty {
+ string name = 1;
+ repeated string functions = 2;
+}
+
+// Message which encapsulates another message to support a single RPC endpoint
+message WireMessage {
+ string name = 1;
+ bytes wrapped_message = 2;
+}
+
+// Generic wrapper to support any SQL type. Struct-like to work around no polymorphism construct.
+message TypedValue {
+ Rep type = 1; // The actual type that was serialized in the general attribute below
+
+ bool bool_value = 2; // boolean
+ string string_value = 3; // char/varchar
+ sint64 number_value = 4; // var-len encoding lets us shove anything from byte to long
+ // includes numeric types and date/time types.
+ bytes bytes_values = 5; // binary/varbinary
+ double double_value = 6; // big numbers
+ bool null = 7; // a null object
+}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/protobuf/requests.proto
----------------------------------------------------------------------
diff --git a/avatica/src/main/protobuf/requests.proto b/avatica/src/main/protobuf/requests.proto
new file mode 100644
index 0000000..1385c93
--- /dev/null
+++ b/avatica/src/main/protobuf/requests.proto
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+syntax = "proto3";
+
+option java_package = "org.apache.calcite.avatica.proto";
+
+import "common.proto";
+
+// Request for Meta#getCatalogs()
+message CatalogsRequest {
+
+}
+
+// Request for Meta#getDatabaseProperties()
+message DatabasePropertyRequest {
+
+}
+
+// Request for Meta#getSchemas(String, org.apache.calcite.avatica.Meta.Pat)}
+message SchemasRequest {
+ string catalog = 1;
+ string schema_pattern = 2;
+}
+
+// Request for Request for Meta#getTables(String, org.apache.calcite.avatica.Meta.Pat,
+// org.apache.calcite.avatica.Meta.Pat, java.util.List)
+message TablesRequest {
+ string catalog = 1;
+ string schema_pattern = 2;
+ string table_name_pattern = 3;
+ repeated string type_list = 4;
+}
+
+// Request for Meta#getTableTypes()
+message TableTypesRequest {
+
+}
+
+// Request for Meta#getColumns(String, org.apache.calcite.avatica.Meta.Pat,
+// org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat).
+message ColumnsRequest {
+ string catalog = 1;
+ string schema_pattern = 2;
+ string table_name_pattern = 3;
+ string column_name_pattern = 4;
+}
+
+// Request for Meta#getTypeInfo()
+message TypeInfoRequest {
+
+}
+
+// Request for Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)
+message PrepareAndExecuteRequest {
+ string connection_id = 1;
+ string sql = 2;
+ uint64 max_row_count = 3;
+ uint32 statement_id = 4;
+}
+
+// Request for Meta.prepare(Meta.ConnectionHandle, String, long)
+message PrepareRequest {
+ string connection_id = 1;
+ string sql = 2;
+ uint64 max_row_count = 3;
+}
+
+// Request for Meta#fetch(Meta.StatementHandle, List, long, int)
+message FetchRequest {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+ uint64 offset = 3;
+ uint32 fetch_max_row_count = 4; // Maximum number of rows to be returned in the frame. Negative means no limit.
+ repeated TypedValue parameter_values = 5; // List of parameter values if statement is to be executed. Else, none.
+ bool has_parameter_values = 6; // Having an empty list of param values is distinct from a null param list
+}
+
+// Request for Meta#createStatement(Meta.ConnectionHandle)
+message CreateStatementRequest {
+ string connection_id = 1;
+}
+
+// Request for Meta#closeStatement(Meta.StatementHandle)
+message CloseStatementRequest {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+}
+
+// Request for Meta#closeConnection(Meta.ConnectionHandle)
+message CloseConnectionRequest {
+ string connection_id = 1;
+}
+
+message ConnectionSyncRequest {
+ string connection_id = 1;
+ ConnectionProperties conn_props = 2;
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/protobuf/responses.proto
----------------------------------------------------------------------
diff --git a/avatica/src/main/protobuf/responses.proto b/avatica/src/main/protobuf/responses.proto
new file mode 100644
index 0000000..1fad9c8
--- /dev/null
+++ b/avatica/src/main/protobuf/responses.proto
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+syntax = "proto3";
+
+option java_package = "org.apache.calcite.avatica.proto";
+
+import "common.proto";
+
+// Response that contains a result set.
+message ResultSetResponse {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+ bool own_statement = 3;
+ Signature signature = 4;
+ Frame first_frame = 5;
+ uint64 update_count = 6; // -1 for normal result sets, else this response contains a dummy result set
+ // with no signature nor other data.
+}
+
+// Response to PrepareAndExecuteRequest
+message ExecuteResponse {
+ repeated ResultSetResponse results = 1;
+}
+
+// Response to PrepareRequest
+message PrepareResponse {
+ StatementHandle statement = 1;
+}
+
+// Response to FetchRequest
+message FetchResponse {
+ Frame frame = 1;
+}
+
+// Response to CreateStatementRequest
+message CreateStatementResponse {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+}
+
+// Response to CloseStatementRequest
+message CloseStatementResponse {
+
+}
+
+// Response to CloseConnectionRequest {
+message CloseConnectionResponse {
+
+}
+
+// Response to ConnectionSyncRequest
+message ConnectionSyncResponse {
+ ConnectionProperties conn_props = 1;
+}
+
+message DatabasePropertyElement {
+ DatabaseProperty key = 1;
+ TypedValue value = 2;
+}
+
+// Response for Meta#getDatabaseProperties()
+message DatabasePropertyResponse {
+ repeated DatabasePropertyElement props = 1;
+}
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/main/scripts/generate-protobuf.sh
----------------------------------------------------------------------
diff --git a/avatica/src/main/scripts/generate-protobuf.sh b/avatica/src/main/scripts/generate-protobuf.sh
new file mode 100755
index 0000000..c4d3abe
--- /dev/null
+++ b/avatica/src/main/scripts/generate-protobuf.sh
@@ -0,0 +1,99 @@
+#! /usr/bin/env bash
+
+# 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.
+
+# This script will regenerate the protobuf code for Avatica. Slightly
+# modified script over one in Accumulo.
+
+# NOTES:
+# To support this script being called by other modules, only edit the right side.
+# In other scripts, set the variables that diverge from the defaults below, then call this script.
+# Leave the BUILD_DIR and FINAL_DIR alone for Maven builds.
+# ========================================================================================================================
+[[ -z $REQUIRED_PROTOC_VERSION ]] && REQUIRED_PROTOC_VERSION='libprotoc 3.0.0'
+[[ -z $BUILD_DIR ]] && BUILD_DIR='target/proto-tmp'
+[[ -z $FINAL_DIR ]] && FINAL_DIR='src/main'
+# ========================================================================================================================
+
+fail() {
+ echo "$@"
+ exit 1
+}
+
+# Test to see if we have protoc installed
+VERSION=$(protoc --version 2>/dev/null | grep -F "${REQUIRED_PROTOC_VERSION}" | wc -l)
+if [[ $VERSION -ne 1 ]] ; then
+ # Nope: bail
+ echo "****************************************************"
+ echo "*** protoc is not available"
+ echo "*** expecting 'protoc --version' to return ${REQUIRED_PROTOC_VERSION}"
+ echo "*** generated code will not be updated"
+ fail "****************************************************"
+fi
+
+# Ensure output directories are created
+PROTOC_ARGS="-I src/main/protobuf --java_out=$BUILD_DIR"
+rm -rf $BUILD_DIR
+mkdir -p $BUILD_DIR
+
+protoc ${PROTOC_ARGS} src/main/protobuf/*.proto || fail unable to generate Java protocol buffer classes
+
+# For all generated protobuf code, suppress all warnings and add the LICENSE header
+s='@SuppressWarnings({"unused", "rawtypes"})'
+find $BUILD_DIR -name '*.java' -print0 | xargs -0 sed -i.orig -e 's/\(public final class \)/'"$s"' \1/'
+
+PREFIX="/*
+"
+LINE_NOTATION=" *"
+SUFFIX="
+ */"
+FILE_SUFFIX=(.java)
+
+for file in "${FILE_SUFFIX[@]}"; do
+ for f in $(find $BUILD_DIR/ -name "*$file"); do
+ cat - "$f" > "${f}-with-license" <<EOF
+${PREFIX}${LINE_NOTATION} Licensed to the Apache Software Foundation (ASF) under one or more
+${LINE_NOTATION} contributor license agreements. See the NOTICE file distributed with
+${LINE_NOTATION} this work for additional information regarding copyright ownership.
+${LINE_NOTATION} The ASF licenses this file to you under the Apache License, Version 2.0
+${LINE_NOTATION} (the "License"); you may not use this file except in compliance with
+${LINE_NOTATION} the License. You may obtain a copy of the License at
+${LINE_NOTATION}
+${LINE_NOTATION} http://www.apache.org/licenses/LICENSE-2.0
+${LINE_NOTATION}
+${LINE_NOTATION} Unless required by applicable law or agreed to in writing, software
+${LINE_NOTATION} distributed under the License is distributed on an "AS IS" BASIS,
+${LINE_NOTATION} WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+${LINE_NOTATION} See the License for the specific language governing permissions and
+${LINE_NOTATION} limitations under the License.${SUFFIX}
+EOF
+ done
+done
+
+# For every generated java file, compare it with the version-controlled one, and copy the ones that have changed into place
+SDIR="${BUILD_DIR}/org/apache/calcite/avatica/proto"
+DDIR="${FINAL_DIR}/java/org/apache/calcite/avatica/proto"
+FILE_SUFFIX=(.java)
+mkdir -p "$DDIR"
+for file in "${FILE_SUFFIX[@]}"; do
+ for f in $(find $SDIR -name *$file); do
+ DEST=$DDIR/$(basename "$f")
+ if ! cmp -s "${f}-with-license" "${DEST}" ; then
+ echo cp -f "${f}-with-license" "${DEST}"
+ cp -f "${f}-with-license" "${DEST}" || fail unable to copy files to java workspace
+ fi
+ done
+done
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/test/java/org/apache/calcite/avatica/FrameTest.java
----------------------------------------------------------------------
diff --git a/avatica/src/test/java/org/apache/calcite/avatica/FrameTest.java b/avatica/src/test/java/org/apache/calcite/avatica/FrameTest.java
new file mode 100644
index 0000000..e4d524c
--- /dev/null
+++ b/avatica/src/test/java/org/apache/calcite/avatica/FrameTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.calcite.avatica;
+
+import org.apache.calcite.avatica.Meta.Frame;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests serialization of {@link Frame}.
+ */
+public class FrameTest {
+
+ private void serializeAndTestEquality(Frame frame) {
+ Frame frameCopy = Frame.fromProto(frame.toProto());
+
+ assertEquals(frame.done, frameCopy.done);
+ assertEquals(frame.offset, frameCopy.offset);
+
+ Iterable<Object> origRows = frame.rows;
+ Iterable<Object> copiedRows = frameCopy.rows;
+
+ assertEquals("Expected rows to both be null, or both be non-null",
+ origRows == null, copiedRows == null);
+
+ Iterator<Object> origIter = origRows.iterator();
+ Iterator<Object> copiedIter = copiedRows.iterator();
+ while (origIter.hasNext() && copiedIter.hasNext()) {
+ Object orig = origIter.next();
+ Object copy = copiedIter.next();
+
+ assertEquals(orig == null, copy == null);
+
+ // This is goofy, but it seems like an Array comes from the JDBC implementation but then
+ // the resulting Frame has a List to support the Avatica typed Accessors
+ assertEquals(Object[].class, orig.getClass());
+ assertTrue("Expected List but got " + copy.getClass(), copy instanceof List);
+
+ @SuppressWarnings("unchecked")
+ List<Object> copyList = (List<Object>) copy;
+
+ assertArrayEquals((Object[]) orig, copyList.toArray(new Object[0]));
+ }
+
+ assertEquals(origIter.hasNext(), copiedIter.hasNext());
+ }
+
+ @Test
+ public void testEmpty() {
+ serializeAndTestEquality(Frame.EMPTY);
+ }
+
+ @Test
+ public void testSingleRow() {
+ ArrayList<Object> rows = new ArrayList<>();
+ rows.add(new Object[] {"string", Integer.MAX_VALUE, new Date().getTime()});
+
+ Frame singleRow = new Frame(0, true, rows);
+
+ serializeAndTestEquality(singleRow);
+ }
+
+ @Test
+ public void testMultipleRows() {
+ ArrayList<Object> rows = new ArrayList<>();
+ rows.add(new Object[] {"string", Integer.MAX_VALUE, new Date().getTime()});
+ rows.add(new Object[] {"gnirts", 0, Long.MIN_VALUE});
+ rows.add(new Object[] {"", null, Long.MAX_VALUE});
+
+ Frame singleRow = new Frame(0, true, rows);
+
+ serializeAndTestEquality(singleRow);
+ }
+}
+
+// End FrameTest.java
http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/cb7c213c/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java b/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
new file mode 100644
index 0000000..ab59b4a
--- /dev/null
+++ b/avatica/src/test/java/org/apache/calcite/avatica/remote/ProtobufHandlerTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.calcite.avatica.remote;
+
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.Meta.Frame;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.proto.Responses;
+import org.apache.calcite.avatica.remote.Service.FetchRequest;
+import org.apache.calcite.avatica.remote.Service.FetchResponse;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test basic serialization of objects with protocol buffers.
+ */
+public class ProtobufHandlerTest {
+
+ // Mocks
+ private Service service;
+ private ProtobufTranslation translation;
+
+ // Real objects
+ private ProtobufHandler handler;
+
+ @Before
+ public void setupMocks() {
+ // Mocks
+ service = Mockito.mock(Service.class);
+ translation = Mockito.mock(ProtobufTranslation.class);
+
+ // Real objects
+ handler = new ProtobufHandler(service, translation);
+ }
+
+ @Test
+ public void testFetch() throws Exception {
+ final String connectionId = "cnxn1";
+ final int statementId = 30;
+ final long offset = 10;
+ final int fetchMaxRowCount = 100;
+ final List<Common.TypedValue> values = new ArrayList<>();
+
+ values.add(Common.TypedValue.newBuilder().setType(Common.Rep.BOOLEAN).setBoolValue(true)
+ .build());
+ values.add(Common.TypedValue.newBuilder().setType(Common.Rep.STRING)
+ .setStringValue("my_string").build());
+
+ Requests.FetchRequest protoRequest = Requests.FetchRequest.newBuilder()
+ .setConnectionId(connectionId).setStatementId(statementId)
+ .setOffset(offset).setFetchMaxRowCount(fetchMaxRowCount)
+ .addAllParameterValues(values).build();
+ byte[] serializedRequest = protoRequest.toByteArray();
+
+ FetchRequest request = new FetchRequest().deserialize(protoRequest);
+
+ List<Object> frameRows = new ArrayList<>();
+ frameRows.add(new Object[] {true, "my_string"});
+
+ Meta.Frame frame = Frame.create(0, true, frameRows);
+ FetchResponse response = new FetchResponse(frame);
+
+ when(translation.parseRequest(serializedRequest)).thenReturn(request);
+ when(service.apply(request)).thenReturn(response);
+ when(translation.serializeResponse(response))
+ .thenReturn(response.serialize().toByteArray());
+
+ byte[] serializedResponse = handler.apply(serializedRequest);
+
+ Responses.FetchResponse protoResponse = Responses.FetchResponse.parseFrom(serializedResponse);
+
+ Common.Frame protoFrame = protoResponse.getFrame();
+
+ assertEquals(frame.offset, protoFrame.getOffset());
+ assertEquals(frame.done, protoFrame.getDone());
+
+ List<Common.Row> rows = protoFrame.getRowsList();
+ assertEquals(1, rows.size());
+ Common.Row row = rows.get(0);
+ List<Common.TypedValue> rowValues = row.getValueList();
+ assertEquals(2, rowValues.size());
+
+ Iterator<Common.TypedValue> iter = rowValues.iterator();
+ assertTrue(iter.hasNext());
+ Common.TypedValue value = iter.next();
+ assertEquals(Common.Rep.BOOLEAN, value.getType());
+ assertEquals(true, value.getBoolValue());
+
+ assertTrue(iter.hasNext());
+ value = iter.next();
+ assertEquals(Common.Rep.STRING, value.getType());
+ assertEquals("my_string", value.getStringValue());
+ }
+
+}
+
+// End ProtobufHandlerTest.java