http://git-wip-us.apache.org/repos/asf/calcite/blob/5cee486f/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java ---------------------------------------------------------------------- diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java new file mode 100644 index 0000000..5790848 --- /dev/null +++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java @@ -0,0 +1,2771 @@ +/* + * 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.AvaticaClientRuntimeException; +import org.apache.calcite.avatica.AvaticaConnection; +import org.apache.calcite.avatica.AvaticaSeverity; +import org.apache.calcite.avatica.BuiltInConnectionProperty; +import org.apache.calcite.avatica.ConnectionPropertiesImpl; +import org.apache.calcite.avatica.Meta; +import org.apache.calcite.avatica.QueryState; +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.ByteString; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.HBaseZeroCopyByteString; +import com.google.protobuf.Message; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Properties; + +/** + * API for request-response calls to an Avatica server. + */ +public interface Service { + ResultSetResponse apply(CatalogsRequest request); + ResultSetResponse apply(SchemasRequest request); + ResultSetResponse apply(TablesRequest request); + ResultSetResponse apply(TableTypesRequest request); + ResultSetResponse apply(TypeInfoRequest request); + ResultSetResponse apply(ColumnsRequest request); + PrepareResponse apply(PrepareRequest request); + ExecuteResponse apply(ExecuteRequest request); + ExecuteResponse apply(PrepareAndExecuteRequest request); + SyncResultsResponse apply(SyncResultsRequest request); + FetchResponse apply(FetchRequest request); + CreateStatementResponse apply(CreateStatementRequest request); + CloseStatementResponse apply(CloseStatementRequest request); + OpenConnectionResponse apply(OpenConnectionRequest request); + CloseConnectionResponse apply(CloseConnectionRequest request); + ConnectionSyncResponse apply(ConnectionSyncRequest request); + DatabasePropertyResponse apply(DatabasePropertyRequest request); + CommitResponse apply(CommitRequest request); + RollbackResponse apply(RollbackRequest request); + + /** + * Sets server-level metadata for RPCs. This includes information that is static across all RPCs. + * + * @param metadata The server-level metadata. + */ + void setRpcMetadata(RpcMetadataResponse metadata); + + /** Factory that creates a {@code Service}. */ + interface Factory { + Service create(AvaticaConnection connection); + } + + /** Base class for request and response. */ + abstract class Base { + static final int PRIME = 31; + + protected static int p(int result, Object o) { + return PRIME * result + ((o == null) ? 0 : o.hashCode()); + } + + protected static int p(int result, boolean v) { + return PRIME * result + (v ? 1231 : 1237); + } + + protected static int p(int result, int v) { + return PRIME * result + v; + } + + protected static int p(int result, long v) { + return PRIME * result + (int) (v ^ (v >>> 32)); + } + } + + /** Base class for all service request messages. */ + @JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "request", + defaultImpl = SchemasRequest.class) + @JsonSubTypes({ + @JsonSubTypes.Type(value = CatalogsRequest.class, name = "getCatalogs"), + @JsonSubTypes.Type(value = SchemasRequest.class, name = "getSchemas"), + @JsonSubTypes.Type(value = TablesRequest.class, name = "getTables"), + @JsonSubTypes.Type(value = TableTypesRequest.class, name = "getTableTypes"), + @JsonSubTypes.Type(value = TypeInfoRequest.class, name = "getTypeInfo"), + @JsonSubTypes.Type(value = ColumnsRequest.class, name = "getColumns"), + @JsonSubTypes.Type(value = ExecuteRequest.class, name = "execute"), + @JsonSubTypes.Type(value = PrepareRequest.class, name = "prepare"), + @JsonSubTypes.Type(value = PrepareAndExecuteRequest.class, + name = "prepareAndExecute"), + @JsonSubTypes.Type(value = FetchRequest.class, name = "fetch"), + @JsonSubTypes.Type(value = CreateStatementRequest.class, + name = "createStatement"), + @JsonSubTypes.Type(value = CloseStatementRequest.class, + name = "closeStatement"), + @JsonSubTypes.Type(value = OpenConnectionRequest.class, + name = "openConnection"), + @JsonSubTypes.Type(value = CloseConnectionRequest.class, + name = "closeConnection"), + @JsonSubTypes.Type(value = ConnectionSyncRequest.class, name = "connectionSync"), + @JsonSubTypes.Type(value = DatabasePropertyRequest.class, name = "databaseProperties"), + @JsonSubTypes.Type(value = SyncResultsRequest.class, name = "syncResults"), + @JsonSubTypes.Type(value = CommitRequest.class, name = "commit"), + @JsonSubTypes.Type(value = RollbackRequest.class, name = "rollback") }) + abstract class Request extends Base { + abstract Response accept(Service service); + abstract Request deserialize(Message genericMsg); + abstract Message serialize(); + } + + /** Base class for all service response messages. */ + @JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + property = "response", + defaultImpl = ResultSetResponse.class) + @JsonSubTypes({ + @JsonSubTypes.Type(value = OpenConnectionResponse.class, name = "openConnection"), + @JsonSubTypes.Type(value = ResultSetResponse.class, name = "resultSet"), + @JsonSubTypes.Type(value = PrepareResponse.class, name = "prepare"), + @JsonSubTypes.Type(value = FetchResponse.class, name = "fetch"), + @JsonSubTypes.Type(value = CreateStatementResponse.class, + name = "createStatement"), + @JsonSubTypes.Type(value = CloseStatementResponse.class, + name = "closeStatement"), + @JsonSubTypes.Type(value = CloseConnectionResponse.class, + name = "closeConnection"), + @JsonSubTypes.Type(value = ConnectionSyncResponse.class, name = "connectionSync"), + @JsonSubTypes.Type(value = DatabasePropertyResponse.class, name = "databaseProperties"), + @JsonSubTypes.Type(value = ExecuteResponse.class, name = "executeResults"), + @JsonSubTypes.Type(value = ErrorResponse.class, name = "error"), + @JsonSubTypes.Type(value = SyncResultsResponse.class, name = "syncResults"), + @JsonSubTypes.Type(value = RpcMetadataResponse.class, name = "rpcMetadata"), + @JsonSubTypes.Type(value = CommitResponse.class, name = "commit"), + @JsonSubTypes.Type(value = RollbackResponse.class, name = "rollback") }) + abstract class Response extends Base { + abstract Response deserialize(Message genericMsg); + abstract Message serialize(); + } + + /** Request for + * {@link org.apache.calcite.avatica.Meta#getCatalogs(Meta.ConnectionHandle)}. */ + class CatalogsRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CatalogsRequest. + getDescriptor().findFieldByNumber(Requests.CatalogsRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + + public CatalogsRequest() { + connectionId = null; + } + + @JsonCreator + public CatalogsRequest(@JsonProperty("connectionId") String connectionId) { + this.connectionId = connectionId; + } + + ResultSetResponse accept(Service service) { + return service.apply(this); + } + + @Override CatalogsRequest deserialize(Message genericMsg) { + final Requests.CatalogsRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.CatalogsRequest.class); + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + return new CatalogsRequest(connectionId); + } + + @Override Requests.CatalogsRequest serialize() { + Requests.CatalogsRequest.Builder builder = Requests.CatalogsRequest.newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CatalogsRequest + && Objects.equals(connectionId, ((CatalogsRequest) o).connectionId); + } + } + + /** Request for + * {@link org.apache.calcite.avatica.Meta#getDatabaseProperties(Meta.ConnectionHandle)}. */ + class DatabasePropertyRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = + Requests.DatabasePropertyRequest.getDescriptor(). + findFieldByNumber(Requests.DatabasePropertyRequest.CONNECTION_ID_FIELD_NUMBER); + + public final String connectionId; + + public DatabasePropertyRequest() { + connectionId = null; + } + + @JsonCreator + public DatabasePropertyRequest(@JsonProperty("connectionId") String connectionId) { + this.connectionId = connectionId; + } + + DatabasePropertyResponse accept(Service service) { + return service.apply(this); + } + + @Override DatabasePropertyRequest deserialize(Message genericMsg) { + final Requests.DatabasePropertyRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.DatabasePropertyRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + return new DatabasePropertyRequest(connectionId); + } + + @Override Requests.DatabasePropertyRequest serialize() { + Requests.DatabasePropertyRequest.Builder builder = + Requests.DatabasePropertyRequest.newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof DatabasePropertyRequest + && Objects.equals(connectionId, ((DatabasePropertyRequest) o).connectionId); + } + } + + /** Request for + * {@link Meta#getSchemas(Meta.ConnectionHandle, String, Meta.Pat)}. */ + class SchemasRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.SchemasRequest. + getDescriptor().findFieldByNumber(Requests.SchemasRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.SchemasRequest. + getDescriptor().findFieldByNumber(Requests.SchemasRequest.CATALOG_FIELD_NUMBER); + private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.SchemasRequest. + getDescriptor().findFieldByNumber(Requests.SchemasRequest.SCHEMA_PATTERN_FIELD_NUMBER); + + public final String connectionId; + public final String catalog; + public final String schemaPattern; + + SchemasRequest() { + connectionId = null; + catalog = null; + schemaPattern = null; + } + + @JsonCreator + public SchemasRequest(@JsonProperty("connectionId") String connectionId, + @JsonProperty("catalog") String catalog, + @JsonProperty("schemaPattern") String schemaPattern) { + this.connectionId = connectionId; + this.catalog = catalog; + this.schemaPattern = schemaPattern; + } + + ResultSetResponse accept(Service service) { + return service.apply(this); + } + + @Override SchemasRequest deserialize(Message genericMsg) { + final Requests.SchemasRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.SchemasRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + String catalog = null; + if (msg.hasField(CATALOG_DESCRIPTOR)) { + catalog = msg.getCatalog(); + } + + String schemaPattern = null; + if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) { + schemaPattern = msg.getSchemaPattern(); + } + + return new SchemasRequest(connectionId, catalog, schemaPattern); + } + + @Override Requests.SchemasRequest serialize() { + Requests.SchemasRequest.Builder builder = Requests.SchemasRequest.newBuilder(); + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + if (null != catalog) { + builder.setCatalog(catalog); + } + if (null != schemaPattern) { + builder.setSchemaPattern(schemaPattern); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + result = p(result, catalog); + result = p(result, schemaPattern); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof SchemasRequest + && Objects.equals(connectionId, ((SchemasRequest) o).connectionId) + && Objects.equals(catalog, ((SchemasRequest) o).catalog) + && Objects.equals(schemaPattern, ((SchemasRequest) o).schemaPattern); + } + } + + /** Request for + * {@link Meta#getTables(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat, java.util.List)} + */ + class TablesRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TablesRequest. + getDescriptor().findFieldByNumber(Requests.TablesRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.TablesRequest. + getDescriptor().findFieldByNumber(Requests.TablesRequest.CATALOG_FIELD_NUMBER); + private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.TablesRequest. + getDescriptor().findFieldByNumber(Requests.TablesRequest.SCHEMA_PATTERN_FIELD_NUMBER); + private static final FieldDescriptor TABLE_NAME_PATTERN_DESCRIPTOR = Requests.TablesRequest. + getDescriptor().findFieldByNumber(Requests.TablesRequest.TABLE_NAME_PATTERN_FIELD_NUMBER); + + public final String connectionId; + public final String catalog; + public final String schemaPattern; + public final String tableNamePattern; + public final List<String> typeList; + + TablesRequest() { + connectionId = null; + catalog = null; + schemaPattern = null; + tableNamePattern = null; + typeList = null; + } + + @JsonCreator + public TablesRequest(@JsonProperty("connectionId") String connectionId, + @JsonProperty("catalog") String catalog, + @JsonProperty("schemaPattern") String schemaPattern, + @JsonProperty("tableNamePattern") String tableNamePattern, + @JsonProperty("typeList") List<String> typeList) { + this.connectionId = connectionId; + this.catalog = catalog; + this.schemaPattern = schemaPattern; + this.tableNamePattern = tableNamePattern; + this.typeList = typeList; + } + + @Override Response accept(Service service) { + return service.apply(this); + } + + @Override Request deserialize(Message genericMsg) { + final Requests.TablesRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.TablesRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + String catalog = null; + if (msg.hasField(CATALOG_DESCRIPTOR)) { + catalog = msg.getCatalog(); + } + + String schemaPattern = null; + if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) { + schemaPattern = msg.getSchemaPattern(); + } + + String tableNamePattern = null; + if (msg.hasField(TABLE_NAME_PATTERN_DESCRIPTOR)) { + tableNamePattern = msg.getTableNamePattern(); + } + + // Cannot determine if a value was set for a repeated field. Must use an extra boolean + // parameter to distinguish an empty and null typeList. + List<String> typeList = null; + if (msg.getHasTypeList()) { + typeList = msg.getTypeListList(); + } + + return new TablesRequest(connectionId, catalog, schemaPattern, tableNamePattern, typeList); + } + + @Override Requests.TablesRequest serialize() { + Requests.TablesRequest.Builder builder = Requests.TablesRequest.newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + if (null != catalog) { + builder.setCatalog(catalog); + } + if (null != schemaPattern) { + builder.setSchemaPattern(schemaPattern); + } + if (null != tableNamePattern) { + builder.setTableNamePattern(tableNamePattern); + } + if (null != typeList) { + builder.setHasTypeList(true); + builder.addAllTypeList(typeList); + } else { + builder.setHasTypeList(false); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + result = p(result, catalog); + result = p(result, schemaPattern); + result = p(result, tableNamePattern); + result = p(result, typeList); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof TablesRequest + && Objects.equals(connectionId, ((TablesRequest) o).connectionId) + && Objects.equals(catalog, ((TablesRequest) o).catalog) + && Objects.equals(schemaPattern, ((TablesRequest) o).schemaPattern) + && Objects.equals(tableNamePattern, ((TablesRequest) o).tableNamePattern) + && Objects.equals(typeList, ((TablesRequest) o).typeList); + } + } + + /** + * Request for {@link Meta#getTableTypes(Meta.ConnectionHandle)}. + */ + class TableTypesRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TableTypesRequest. + getDescriptor().findFieldByNumber(Requests.TableTypesRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + + public TableTypesRequest() { + this.connectionId = null; + } + + @JsonCreator + public TableTypesRequest(@JsonProperty("connectionId") String connectionId) { + this.connectionId = connectionId; + } + + @Override ResultSetResponse accept(Service service) { + return service.apply(this); + } + + @Override TableTypesRequest deserialize(Message genericMsg) { + final Requests.TableTypesRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.TableTypesRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + return new TableTypesRequest(connectionId); + } + + @Override Requests.TableTypesRequest serialize() { + Requests.TableTypesRequest.Builder builder = Requests.TableTypesRequest.newBuilder(); + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof TableTypesRequest + && Objects.equals(connectionId, ((TableTypesRequest) o).connectionId); + } + } + + /** Request for + * {@link Meta#getColumns(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat, org.apache.calcite.avatica.Meta.Pat)}. + */ + class ColumnsRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.ColumnsRequest. + getDescriptor().findFieldByNumber(Requests.ColumnsRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor CATALOG_DESCRIPTOR = Requests.ColumnsRequest. + getDescriptor().findFieldByNumber(Requests.ColumnsRequest.CATALOG_FIELD_NUMBER); + private static final FieldDescriptor SCHEMA_PATTERN_DESCRIPTOR = Requests.ColumnsRequest. + getDescriptor().findFieldByNumber(Requests.ColumnsRequest.SCHEMA_PATTERN_FIELD_NUMBER); + private static final FieldDescriptor TABLE_NAME_PATTERN_DESCRIPTOR = Requests.ColumnsRequest. + getDescriptor().findFieldByNumber(Requests.ColumnsRequest.TABLE_NAME_PATTERN_FIELD_NUMBER); + private static final FieldDescriptor COLUMN_NAME_PATTERN_DESCRIPTOR = Requests.ColumnsRequest. + getDescriptor().findFieldByNumber(Requests.ColumnsRequest.COLUMN_NAME_PATTERN_FIELD_NUMBER); + + public final String connectionId; + public final String catalog; + public final String schemaPattern; + public final String tableNamePattern; + public final String columnNamePattern; + + ColumnsRequest() { + connectionId = null; + catalog = null; + schemaPattern = null; + tableNamePattern = null; + columnNamePattern = null; + } + + @JsonCreator + public ColumnsRequest(@JsonProperty("connectionId") String connectionId, + @JsonProperty("catalog") String catalog, + @JsonProperty("schemaPattern") String schemaPattern, + @JsonProperty("tableNamePattern") String tableNamePattern, + @JsonProperty("columnNamePattern") String columnNamePattern) { + this.connectionId = connectionId; + this.catalog = catalog; + this.schemaPattern = schemaPattern; + this.tableNamePattern = tableNamePattern; + this.columnNamePattern = columnNamePattern; + } + + ResultSetResponse accept(Service service) { + return service.apply(this); + } + + @Override ColumnsRequest deserialize(Message genericMsg) { + final Requests.ColumnsRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.ColumnsRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + String catalog = null; + if (msg.hasField(CATALOG_DESCRIPTOR)) { + catalog = msg.getCatalog(); + } + + String schemaPattern = null; + if (msg.hasField(SCHEMA_PATTERN_DESCRIPTOR)) { + schemaPattern = msg.getSchemaPattern(); + } + + String tableNamePattern = null; + if (msg.hasField(TABLE_NAME_PATTERN_DESCRIPTOR)) { + tableNamePattern = msg.getTableNamePattern(); + } + + String columnNamePattern = null; + if (msg.hasField(COLUMN_NAME_PATTERN_DESCRIPTOR)) { + columnNamePattern = msg.getColumnNamePattern(); + } + + return new ColumnsRequest(connectionId, catalog, schemaPattern, tableNamePattern, + columnNamePattern); + } + + @Override Requests.ColumnsRequest serialize() { + Requests.ColumnsRequest.Builder builder = Requests.ColumnsRequest.newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + 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() { + int result = 1; + result = p(result, connectionId); + result = p(result, catalog); + result = p(result, columnNamePattern); + result = p(result, schemaPattern); + result = p(result, tableNamePattern); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof ColumnsRequest + && Objects.equals(connectionId, ((ColumnsRequest) o).connectionId) + && Objects.equals(catalog, ((ColumnsRequest) o).catalog) + && Objects.equals(schemaPattern, ((ColumnsRequest) o).schemaPattern) + && Objects.equals(tableNamePattern, ((ColumnsRequest) o).tableNamePattern) + && Objects.equals(columnNamePattern, ((ColumnsRequest) o).columnNamePattern); + } + } + + /** Request for + * {@link Meta#getTypeInfo(Meta.ConnectionHandle)}. */ + class TypeInfoRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.TypeInfoRequest. + getDescriptor().findFieldByNumber(Requests.TypeInfoRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + + public TypeInfoRequest() { + connectionId = null; + } + + @JsonCreator + public TypeInfoRequest(@JsonProperty("connectionId") String connectionId) { + this.connectionId = connectionId; + } + + @Override ResultSetResponse accept(Service service) { + return service.apply(this); + } + + @Override TypeInfoRequest deserialize(Message genericMsg) { + final Requests.TypeInfoRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.TypeInfoRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + return new TypeInfoRequest(connectionId); + } + + @Override Requests.TypeInfoRequest serialize() { + Requests.TypeInfoRequest.Builder builder = Requests.TypeInfoRequest.newBuilder(); + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof TypeInfoRequest + && Objects.equals(connectionId, ((TypeInfoRequest) o).connectionId); + } + } + + /** Response that contains a result set. + * + * <p>Regular result sets have {@code updateCount} -1; + * any other value means a dummy result set that is just a count, and has + * no signature and no other data. + * + * <p>Several types of request, including + * {@link org.apache.calcite.avatica.Meta#getCatalogs(Meta.ConnectionHandle)} and + * {@link org.apache.calcite.avatica.Meta#getSchemas(Meta.ConnectionHandle, String, org.apache.calcite.avatica.Meta.Pat)} + * {@link Meta#getTables(Meta.ConnectionHandle, String, Meta.Pat, Meta.Pat, List)} + * {@link Meta#getTableTypes(Meta.ConnectionHandle)} + * return this response. */ + class ResultSetResponse extends Response { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses.ResultSetResponse. + getDescriptor().findFieldByNumber(Responses.ResultSetResponse.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor SIGNATURE_DESCRIPTOR = Responses.ResultSetResponse. + getDescriptor().findFieldByNumber(Responses.ResultSetResponse.SIGNATURE_FIELD_NUMBER); + private static final FieldDescriptor FIRST_FRAME_DESCRIPTOR = Responses.ResultSetResponse. + getDescriptor().findFieldByNumber(Responses.ResultSetResponse.FIRST_FRAME_FIELD_NUMBER); + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ResultSetResponse. + getDescriptor().findFieldByNumber(Responses.ResultSetResponse.METADATA_FIELD_NUMBER); + + public final String connectionId; + public final int statementId; + public final boolean ownStatement; + public final Meta.Signature signature; + public final Meta.Frame firstFrame; + public final long updateCount; + public final RpcMetadataResponse rpcMetadata; + + ResultSetResponse() { + connectionId = null; + statementId = 0; + ownStatement = false; + signature = null; + firstFrame = null; + updateCount = 0; + rpcMetadata = null; + } + + @JsonCreator + public ResultSetResponse( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("statementId") int statementId, + @JsonProperty("ownStatement") boolean ownStatement, + @JsonProperty("signature") Meta.Signature signature, + @JsonProperty("firstFrame") Meta.Frame firstFrame, + @JsonProperty("updateCount") long updateCount, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.connectionId = connectionId; + this.statementId = statementId; + this.ownStatement = ownStatement; + this.signature = signature; + this.firstFrame = firstFrame; + this.updateCount = updateCount; + this.rpcMetadata = rpcMetadata; + } + + @Override ResultSetResponse deserialize(Message genericMsg) { + final Responses.ResultSetResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.ResultSetResponse.class); + + return fromProto(msg); + } + + static ResultSetResponse fromProto(Responses.ResultSetResponse msg) { + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + Meta.Signature signature = null; + if (msg.hasField(SIGNATURE_DESCRIPTOR)) { + signature = Meta.Signature.fromProto(msg.getSignature()); + } + + Meta.Frame frame = null; + if (msg.hasField(FIRST_FRAME_DESCRIPTOR)) { + frame = Meta.Frame.fromProto(msg.getFirstFrame()); + } + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new ResultSetResponse(connectionId, msg.getStatementId(), msg.getOwnStatement(), + signature, frame, msg.getUpdateCount(), metadata); + } + + @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()); + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + result = p(result, firstFrame); + result = p(result, ownStatement); + result = p(result, signature); + result = p(result, statementId); + result = p(result, updateCount); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof ResultSetResponse + && statementId == ((ResultSetResponse) o).statementId + && ownStatement == ((ResultSetResponse) o).ownStatement + && updateCount == ((ResultSetResponse) o).updateCount + && Objects.equals(connectionId, ((ResultSetResponse) o).connectionId) + && Objects.equals(firstFrame, ((ResultSetResponse) o).firstFrame) + && Objects.equals(signature, ((ResultSetResponse) o).signature) + && Objects.equals(rpcMetadata, ((ResultSetResponse) o).rpcMetadata); + } + } + + /** Request for + * {@link Meta#prepareAndExecute(Meta.StatementHandle, String, long, Meta.PrepareCallback)}. */ + class PrepareAndExecuteRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests. + PrepareAndExecuteRequest.getDescriptor().findFieldByNumber( + Requests.PrepareAndExecuteRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor SQL_DESCRIPTOR = Requests. + PrepareAndExecuteRequest.getDescriptor().findFieldByNumber( + Requests.PrepareAndExecuteRequest.SQL_FIELD_NUMBER); + + public final String connectionId; + public final String sql; + public final long maxRowCount; + public final int statementId; + + PrepareAndExecuteRequest() { + connectionId = null; + sql = null; + maxRowCount = 0; + statementId = 0; + } + + @JsonCreator + public PrepareAndExecuteRequest( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("statementId") int statementId, + @JsonProperty("sql") String sql, + @JsonProperty("maxRowCount") long maxRowCount) { + this.connectionId = connectionId; + this.statementId = statementId; + this.sql = sql; + this.maxRowCount = maxRowCount; + } + + @Override ExecuteResponse accept(Service service) { + return service.apply(this); + } + + @Override PrepareAndExecuteRequest deserialize(Message genericMsg) { + final Requests.PrepareAndExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.PrepareAndExecuteRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + String sql = null; + if (msg.hasField(SQL_DESCRIPTOR)) { + 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() { + int result = 1; + result = p(result, connectionId); + result = p(result, maxRowCount); + result = p(result, sql); + result = p(result, statementId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof PrepareAndExecuteRequest + && statementId == ((PrepareAndExecuteRequest) o).statementId + && maxRowCount == ((PrepareAndExecuteRequest) o).maxRowCount + && Objects.equals(connectionId, ((PrepareAndExecuteRequest) o).connectionId) + && Objects.equals(sql, ((PrepareAndExecuteRequest) o).sql); + } + } + + /** Request for + * {@link org.apache.calcite.avatica.Meta#execute}. */ + class ExecuteRequest extends Request { + private static final FieldDescriptor STATEMENT_HANDLE_DESCRIPTOR = Requests.ExecuteRequest. + getDescriptor().findFieldByNumber(Requests.ExecuteRequest.STATEMENTHANDLE_FIELD_NUMBER); + public final Meta.StatementHandle statementHandle; + public final List<TypedValue> parameterValues; + public final long maxRowCount; + + ExecuteRequest() { + statementHandle = null; + parameterValues = null; + maxRowCount = 0; + } + + @JsonCreator + public ExecuteRequest( + @JsonProperty("statementHandle") Meta.StatementHandle statementHandle, + @JsonProperty("parameterValues") List<TypedValue> parameterValues, + @JsonProperty("maxRowCount") long maxRowCount) { + this.statementHandle = statementHandle; + this.parameterValues = parameterValues; + this.maxRowCount = maxRowCount; + } + + @Override ExecuteResponse accept(Service service) { + return service.apply(this); + } + + @Override ExecuteRequest deserialize(Message genericMsg) { + final Requests.ExecuteRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.ExecuteRequest.class); + + Meta.StatementHandle statemetnHandle = null; + if (msg.hasField(STATEMENT_HANDLE_DESCRIPTOR)) { + statemetnHandle = Meta.StatementHandle.fromProto(msg.getStatementHandle()); + } + + List<TypedValue> values = null; + if (msg.getHasParameterValues()) { + values = new ArrayList<>(msg.getParameterValuesCount()); + for (Common.TypedValue valueProto : msg.getParameterValuesList()) { + values.add(TypedValue.fromProto(valueProto)); + } + } + + return new ExecuteRequest(statemetnHandle, values, msg.getMaxRowCount()); + } + + @Override Requests.ExecuteRequest serialize() { + Requests.ExecuteRequest.Builder builder = Requests.ExecuteRequest.newBuilder(); + + if (null != statementHandle) { + builder.setStatementHandle(statementHandle.toProto()); + } + + if (null != parameterValues) { + builder.setHasParameterValues(true); + for (TypedValue paramValue : parameterValues) { + if (paramValue == null) { + builder.addParameterValues(TypedValue.NULL.toProto()); + } else { + builder.addParameterValues(paramValue.toProto()); + } + } + } else { + builder.setHasParameterValues(false); + } + + builder.setMaxRowCount(maxRowCount); + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, statementHandle); + result = p(result, parameterValues); + result = p(result, maxRowCount); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof ExecuteRequest + && maxRowCount == ((ExecuteRequest) o).maxRowCount + && Objects.equals(statementHandle, ((ExecuteRequest) o).statementHandle) + && Objects.equals(parameterValues, ((ExecuteRequest) o).parameterValues); + } + } + + /** Response to a + * {@link org.apache.calcite.avatica.remote.Service.PrepareAndExecuteRequest}. */ + class ExecuteResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ExecuteResponse. + getDescriptor().findFieldByNumber(Responses.ExecuteResponse.METADATA_FIELD_NUMBER); + public final List<ResultSetResponse> results; + public boolean missingStatement = false; + public final RpcMetadataResponse rpcMetadata; + + ExecuteResponse() { + results = null; + rpcMetadata = null; + } + + @JsonCreator + public ExecuteResponse(@JsonProperty("resultSets") List<ResultSetResponse> results, + @JsonProperty("missingStatement") boolean missingStatement, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.results = results; + this.missingStatement = missingStatement; + this.rpcMetadata = rpcMetadata; + } + + @Override ExecuteResponse deserialize(Message genericMsg) { + final Responses.ExecuteResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.ExecuteResponse.class); + + List<Responses.ResultSetResponse> msgResults = msg.getResultsList(); + List<ResultSetResponse> copiedResults = new ArrayList<>(msgResults.size()); + + for (Responses.ResultSetResponse msgResult : msgResults) { + copiedResults.add(ResultSetResponse.fromProto(msgResult)); + } + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new ExecuteResponse(copiedResults, msg.getMissingStatement(), metadata); + } + + @Override Responses.ExecuteResponse serialize() { + Responses.ExecuteResponse.Builder builder = Responses.ExecuteResponse.newBuilder(); + + if (null != results) { + for (ResultSetResponse result : results) { + builder.addResults(result.serialize()); + } + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.setMissingStatement(missingStatement).build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, results); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof ExecuteResponse + && Objects.equals(results, ((ExecuteResponse) o).results) + && Objects.equals(rpcMetadata, ((ExecuteResponse) o).rpcMetadata); + } + } + + /** Request for + * {@link Meta#prepare(Meta.ConnectionHandle, String, long)}. */ + class PrepareRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.PrepareRequest. + getDescriptor().findFieldByNumber(Requests.PrepareRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor SQL_DESCRIPTOR = Requests.PrepareRequest. + getDescriptor().findFieldByNumber(Requests.PrepareRequest.SQL_FIELD_NUMBER); + public final String connectionId; + public final String sql; + public final long maxRowCount; + + PrepareRequest() { + connectionId = null; + sql = null; + maxRowCount = 0; + } + + @JsonCreator + public PrepareRequest( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("sql") String sql, + @JsonProperty("maxRowCount") long maxRowCount) { + this.connectionId = connectionId; + this.sql = sql; + this.maxRowCount = maxRowCount; + } + + @Override PrepareResponse accept(Service service) { + return service.apply(this); + } + + @Override PrepareRequest deserialize(Message genericMsg) { + final Requests.PrepareRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.PrepareRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + String sql = null; + if (msg.hasField(SQL_DESCRIPTOR)) { + 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() { + int result = 1; + result = p(result, connectionId); + result = p(result, maxRowCount); + result = p(result, sql); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof PrepareRequest + && maxRowCount == ((PrepareRequest) o).maxRowCount + && Objects.equals(connectionId, ((PrepareRequest) o).connectionId) + && Objects.equals(sql, ((PrepareRequest) o).sql); + } + } + + /** Response from + * {@link org.apache.calcite.avatica.remote.Service.PrepareRequest}. */ + class PrepareResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.PrepareResponse. + getDescriptor().findFieldByNumber(Responses.PrepareResponse.METADATA_FIELD_NUMBER); + public final Meta.StatementHandle statement; + public final RpcMetadataResponse rpcMetadata; + + PrepareResponse() { + statement = null; + rpcMetadata = null; + } + + @JsonCreator + public PrepareResponse( + @JsonProperty("statement") Meta.StatementHandle statement, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.statement = statement; + this.rpcMetadata = rpcMetadata; + } + + @Override PrepareResponse deserialize(Message genericMsg) { + final Responses.PrepareResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.PrepareResponse.class); + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new PrepareResponse(Meta.StatementHandle.fromProto(msg.getStatement()), metadata); + } + + @Override Responses.PrepareResponse serialize() { + Responses.PrepareResponse.Builder builder = Responses.PrepareResponse.newBuilder(); + + if (null != statement) { + builder.setStatement(statement.toProto()); + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, statement); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof PrepareResponse + && Objects.equals(statement, ((PrepareResponse) o).statement) + && Objects.equals(rpcMetadata, ((PrepareResponse) o).rpcMetadata); + } + } + + /** Request for + * {@link Meta#fetch}. */ + class FetchRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.FetchRequest. + getDescriptor().findFieldByNumber(Requests.FetchRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + public final int statementId; + public final long offset; + /** Maximum number of rows to be returned in the frame. Negative means no + * limit. */ + public final int fetchMaxRowCount; + + FetchRequest() { + connectionId = null; + statementId = 0; + offset = 0; + fetchMaxRowCount = 0; + } + + @JsonCreator + public FetchRequest( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("statementId") int statementId, + @JsonProperty("offset") long offset, + @JsonProperty("fetchMaxRowCount") int fetchMaxRowCount) { + this.connectionId = connectionId; + this.statementId = statementId; + this.offset = offset; + this.fetchMaxRowCount = fetchMaxRowCount; + } + + @Override FetchResponse accept(Service service) { + return service.apply(this); + } + + @Override FetchRequest deserialize(Message genericMsg) { + final Requests.FetchRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.FetchRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + return new FetchRequest(connectionId, msg.getStatementId(), msg.getOffset(), + msg.getFetchMaxRowCount()); + } + + @Override Requests.FetchRequest serialize() { + Requests.FetchRequest.Builder builder = Requests.FetchRequest.newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + builder.setStatementId(statementId); + builder.setOffset(offset); + builder.setFetchMaxRowCount(fetchMaxRowCount); + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + result = p(result, fetchMaxRowCount); + result = p(result, offset); + result = p(result, statementId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof FetchRequest + && statementId == ((FetchRequest) o).statementId + && offset == ((FetchRequest) o).offset + && fetchMaxRowCount == ((FetchRequest) o).fetchMaxRowCount + && Objects.equals(connectionId, ((FetchRequest) o).connectionId); + } + } + + /** Response from + * {@link org.apache.calcite.avatica.remote.Service.FetchRequest}. */ + class FetchResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.FetchResponse. + getDescriptor().findFieldByNumber(Responses.FetchResponse.METADATA_FIELD_NUMBER); + public final Meta.Frame frame; + public boolean missingStatement = false; + public boolean missingResults = false; + public final RpcMetadataResponse rpcMetadata; + + FetchResponse() { + frame = null; + rpcMetadata = null; + } + + @JsonCreator + public FetchResponse(@JsonProperty("frame") Meta.Frame frame, + @JsonProperty("missingStatement") boolean missingStatement, + @JsonProperty("missingResults") boolean missingResults, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.frame = frame; + this.missingStatement = missingStatement; + this.missingResults = missingResults; + this.rpcMetadata = rpcMetadata; + } + + @Override FetchResponse deserialize(Message genericMsg) { + final Responses.FetchResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.FetchResponse.class); + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new FetchResponse(Meta.Frame.fromProto(msg.getFrame()), msg.getMissingStatement(), + msg.getMissingResults(), metadata); + } + + @Override Responses.FetchResponse serialize() { + Responses.FetchResponse.Builder builder = Responses.FetchResponse.newBuilder(); + + if (null != frame) { + builder.setFrame(frame.toProto()); + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.setMissingStatement(missingStatement) + .setMissingResults(missingResults).build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, frame); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof FetchResponse + && Objects.equals(frame, ((FetchResponse) o).frame) + && Objects.equals(rpcMetadata, ((FetchResponse) o).rpcMetadata) + && missingStatement == ((FetchResponse) o).missingStatement; + } + } + + /** Request for + * {@link org.apache.calcite.avatica.Meta#createStatement(org.apache.calcite.avatica.Meta.ConnectionHandle)}. */ + class CreateStatementRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CreateStatementRequest. + getDescriptor().findFieldByNumber( + Requests.CreateStatementRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + + CreateStatementRequest() { + connectionId = null; + } + + @JsonCreator + public CreateStatementRequest( + @JsonProperty("signature") String connectionId) { + this.connectionId = connectionId; + } + + @Override CreateStatementResponse accept(Service service) { + return service.apply(this); + } + + @Override CreateStatementRequest deserialize(Message genericMsg) { + final Requests.CreateStatementRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.CreateStatementRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + 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() { + int result = 1; + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CreateStatementRequest + && Objects.equals(connectionId, ((CreateStatementRequest) o).connectionId); + } + } + + /** Response from + * {@link org.apache.calcite.avatica.remote.Service.CreateStatementRequest}. */ + class CreateStatementResponse extends Response { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses. + CreateStatementResponse.getDescriptor().findFieldByNumber( + Responses.CreateStatementResponse.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses. + CreateStatementResponse.getDescriptor().findFieldByNumber( + Responses.CreateStatementResponse.METADATA_FIELD_NUMBER); + public final String connectionId; + public final int statementId; + public final RpcMetadataResponse rpcMetadata; + + CreateStatementResponse() { + connectionId = null; + statementId = 0; + rpcMetadata = null; + } + + @JsonCreator + public CreateStatementResponse( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("statementId") int statementId, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.connectionId = connectionId; + this.statementId = statementId; + this.rpcMetadata = rpcMetadata; + } + + @Override CreateStatementResponse deserialize(Message genericMsg) { + final Responses.CreateStatementResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.CreateStatementResponse.class); + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new CreateStatementResponse(connectionId, msg.getStatementId(), metadata); + } + + @Override Responses.CreateStatementResponse serialize() { + Responses.CreateStatementResponse.Builder builder = Responses.CreateStatementResponse + .newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + builder.setStatementId(statementId); + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + result = p(result, statementId); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CreateStatementResponse + && statementId == ((CreateStatementResponse) o).statementId + && Objects.equals(connectionId, ((CreateStatementResponse) o).connectionId) + && Objects.equals(rpcMetadata, ((CreateStatementResponse) o).rpcMetadata); + } + } + + /** Request for + * {@link org.apache.calcite.avatica.Meta#closeStatement(org.apache.calcite.avatica.Meta.StatementHandle)}. */ + class CloseStatementRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CloseStatementRequest. + getDescriptor().findFieldByNumber( + Requests.CloseStatementRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + public final int statementId; + + CloseStatementRequest() { + connectionId = null; + statementId = 0; + } + + @JsonCreator + public CloseStatementRequest( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("statementId") int statementId) { + this.connectionId = connectionId; + this.statementId = statementId; + } + + @Override CloseStatementResponse accept(Service service) { + return service.apply(this); + } + + @Override CloseStatementRequest deserialize(Message genericMsg) { + final Requests.CloseStatementRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.CloseStatementRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + 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() { + int result = 1; + result = p(result, connectionId); + result = p(result, statementId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CloseStatementRequest + && statementId == ((CloseStatementRequest) o).statementId + && Objects.equals(connectionId, ((CloseStatementRequest) o).connectionId); + } + } + + /** Response from + * {@link org.apache.calcite.avatica.remote.Service.CloseStatementRequest}. */ + class CloseStatementResponse extends Response { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Responses. + CloseStatementResponse.getDescriptor().findFieldByNumber( + Responses.CloseStatementResponse.METADATA_FIELD_NUMBER); + + public final RpcMetadataResponse rpcMetadata; + + public CloseStatementResponse() { + rpcMetadata = null; + } + + @JsonCreator + public CloseStatementResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.rpcMetadata = rpcMetadata; + } + + @Override CloseStatementResponse deserialize(Message genericMsg) { + final Responses.CloseStatementResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.CloseStatementResponse.class); + RpcMetadataResponse metadata = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new CloseStatementResponse(metadata); + } + + @Override Responses.CloseStatementResponse serialize() { + Responses.CloseStatementResponse.Builder builder = + Responses.CloseStatementResponse.newBuilder(); + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CloseStatementResponse + && Objects.equals(rpcMetadata, ((CloseStatementResponse) o).rpcMetadata); + } + } + + /** Request for + * {@link Meta#openConnection}. */ + class OpenConnectionRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.OpenConnectionRequest + .getDescriptor().findFieldByNumber( + Requests.OpenConnectionRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + public final Map<String, String> info; + + public OpenConnectionRequest() { + connectionId = null; + info = null; + } + + @JsonCreator + public OpenConnectionRequest(@JsonProperty("connectionId") String connectionId, + @JsonProperty("info") Map<String, String> info) { + this.connectionId = connectionId; + this.info = info; + } + + @Override OpenConnectionResponse accept(Service service) { + return service.apply(this); + } + + /** + * Serializes the necessary properties into a Map. + * + * @param props The properties to serialize. + * @return A representation of the Properties as a Map. + */ + public static Map<String, String> serializeProperties(Properties props) { + Map<String, String> infoAsString = new HashMap<>(); + for (Map.Entry<Object, Object> entry : props.entrySet()) { + // Determine if this is a property we want to forward to the server + boolean localProperty = false; + for (BuiltInConnectionProperty prop : BuiltInConnectionProperty.values()) { + if (prop.camelName().equals(entry.getKey())) { + localProperty = true; + break; + } + } + + if (!localProperty) { + infoAsString.put(entry.getKey().toString(), entry.getValue().toString()); + } + } + return infoAsString; + } + + @Override Request deserialize(Message genericMsg) { + final Requests.OpenConnectionRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.OpenConnectionRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + Map<String, String> info = msg.getInfo(); + if (info.isEmpty()) { + info = null; + } + + return new OpenConnectionRequest(connectionId, info); + } + + @Override Message serialize() { + Requests.OpenConnectionRequest.Builder builder = Requests.OpenConnectionRequest.newBuilder(); + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + if (null != info) { + builder.getMutableInfo().putAll(info); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connectionId); + result = p(result, info); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof OpenConnectionRequest + && Objects.equals(connectionId, ((OpenConnectionRequest) o).connectionId) + && Objects.equals(info, ((OpenConnectionRequest) o).info); + } + } + + /** Response from + * {@link org.apache.calcite.avatica.remote.Service.OpenConnectionRequest}. */ + class OpenConnectionResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.OpenConnectionResponse + .getDescriptor().findFieldByNumber( + Responses.OpenConnectionResponse.METADATA_FIELD_NUMBER); + public final RpcMetadataResponse rpcMetadata; + + public OpenConnectionResponse() { + rpcMetadata = null; + } + + @JsonCreator + public OpenConnectionResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.rpcMetadata = rpcMetadata; + } + + @Override OpenConnectionResponse deserialize(Message genericMsg) { + final Responses.OpenConnectionResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.OpenConnectionResponse.class); + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new OpenConnectionResponse(metadata); + } + + @Override Responses.OpenConnectionResponse serialize() { + Responses.OpenConnectionResponse.Builder builder = + Responses.OpenConnectionResponse.newBuilder(); + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof OpenConnectionResponse + && Objects.equals(rpcMetadata, ((OpenConnectionResponse) o).rpcMetadata); + } + } + + /** Request for + * {@link Meta#closeConnection(org.apache.calcite.avatica.Meta.ConnectionHandle)}. */ + class CloseConnectionRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.CloseConnectionRequest + .getDescriptor().findFieldByNumber( + Requests.CloseConnectionRequest.CONNECTION_ID_FIELD_NUMBER); + public final String connectionId; + + CloseConnectionRequest() { + connectionId = null; + } + + @JsonCreator + public CloseConnectionRequest( + @JsonProperty("connectionId") String connectionId) { + this.connectionId = connectionId; + } + + @Override CloseConnectionResponse accept(Service service) { + return service.apply(this); + } + + @Override CloseConnectionRequest deserialize(Message genericMsg) { + final Requests.CloseConnectionRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.CloseConnectionRequest.class); + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + 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() { + int result = 1; + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CloseConnectionRequest + && Objects.equals(connectionId, ((CloseConnectionRequest) o).connectionId); + } + } + + /** Response from + * {@link org.apache.calcite.avatica.remote.Service.CloseConnectionRequest}. */ + class CloseConnectionResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.CloseConnectionResponse + .getDescriptor().findFieldByNumber( + Responses.CloseConnectionResponse.METADATA_FIELD_NUMBER); + + public final RpcMetadataResponse rpcMetadata; + + public CloseConnectionResponse() { + rpcMetadata = null; + } + + @JsonCreator + public CloseConnectionResponse(@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.rpcMetadata = rpcMetadata; + } + + @Override CloseConnectionResponse deserialize(Message genericMsg) { + final Responses.CloseConnectionResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.CloseConnectionResponse.class); + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new CloseConnectionResponse(metadata); + } + + @Override Responses.CloseConnectionResponse serialize() { + Responses.CloseConnectionResponse.Builder builder = + Responses.CloseConnectionResponse.newBuilder(); + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof CloseConnectionResponse + && Objects.equals(rpcMetadata, ((CloseConnectionResponse) o).rpcMetadata); + } + } + + /** Request for {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */ + class ConnectionSyncRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.ConnectionSyncRequest + .getDescriptor().findFieldByNumber( + Requests.ConnectionSyncRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor CONN_PROPS_DESCRIPTOR = Requests.ConnectionSyncRequest + .getDescriptor().findFieldByNumber(Requests.ConnectionSyncRequest.CONN_PROPS_FIELD_NUMBER); + + public final String connectionId; + public final Meta.ConnectionProperties connProps; + + ConnectionSyncRequest() { + connectionId = null; + connProps = null; + } + + @JsonCreator + public ConnectionSyncRequest( + @JsonProperty("connectionId") String connectionId, + @JsonProperty("connProps") Meta.ConnectionProperties connProps) { + this.connectionId = connectionId; + this.connProps = connProps; + } + + @Override ConnectionSyncResponse accept(Service service) { + return service.apply(this); + } + + @Override ConnectionSyncRequest deserialize(Message genericMsg) { + final Requests.ConnectionSyncRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.ConnectionSyncRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + Meta.ConnectionProperties connProps = null; + if (msg.hasField(CONN_PROPS_DESCRIPTOR)) { + 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() { + int result = 1; + result = p(result, connProps); + result = p(result, connectionId); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof ConnectionSyncRequest + && Objects.equals(connectionId, ((ConnectionSyncRequest) o).connectionId) + && Objects.equals(connProps, ((ConnectionSyncRequest) o).connProps); + } + } + + /** Response for + * {@link Meta#connectionSync(Meta.ConnectionHandle, Meta.ConnectionProperties)}. */ + class ConnectionSyncResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ConnectionSyncResponse + .getDescriptor().findFieldByNumber(Responses.ConnectionSyncResponse.METADATA_FIELD_NUMBER); + public final Meta.ConnectionProperties connProps; + public final RpcMetadataResponse rpcMetadata; + + ConnectionSyncResponse() { + connProps = null; + rpcMetadata = null; + } + + @JsonCreator + public ConnectionSyncResponse(@JsonProperty("connProps") Meta.ConnectionProperties connProps, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.connProps = connProps; + this.rpcMetadata = rpcMetadata; + } + + @Override ConnectionSyncResponse deserialize(Message genericMsg) { + final Responses.ConnectionSyncResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.ConnectionSyncResponse.class); + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new ConnectionSyncResponse(ConnectionPropertiesImpl.fromProto(msg.getConnProps()), + metadata); + } + + @Override Responses.ConnectionSyncResponse serialize() { + Responses.ConnectionSyncResponse.Builder builder = Responses.ConnectionSyncResponse + .newBuilder(); + + if (null != connProps) { + builder.setConnProps(connProps.toProto()); + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, connProps); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof ConnectionSyncResponse + && Objects.equals(connProps, ((ConnectionSyncResponse) o).connProps) + && Objects.equals(rpcMetadata, ((ConnectionSyncResponse) o).rpcMetadata); + } + } + + /** Response for + * {@link Meta#getDatabaseProperties(Meta.ConnectionHandle)}. */ + class DatabasePropertyResponse extends Response { + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.DatabasePropertyResponse + .getDescriptor().findFieldByNumber( + Responses.DatabasePropertyResponse.METADATA_FIELD_NUMBER); + public final Map<Meta.DatabaseProperty, Object> map; + public final RpcMetadataResponse rpcMetadata; + + DatabasePropertyResponse() { + map = null; + rpcMetadata = null; + } + + @JsonCreator + public DatabasePropertyResponse(@JsonProperty("map") Map<Meta.DatabaseProperty, Object> map, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.map = map; + this.rpcMetadata = rpcMetadata; + } + + @Override DatabasePropertyResponse deserialize(Message genericMsg) { + final Responses.DatabasePropertyResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.DatabasePropertyResponse.class); + 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 = (int) value.getNumberValue(); + break; + default: + throw new RuntimeException("Unhandled DatabaseProperty"); + } + + properties.put(dbProp, obj); + } + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new DatabasePropertyResponse(properties, metadata); + } + + @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())); + } + } + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + return builder.build(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, map); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return o == this + || o instanceof DatabasePropertyResponse + && Objects.equals(map, ((DatabasePropertyResponse) o).map) + && Objects.equals(rpcMetadata, ((DatabasePropertyResponse) o).rpcMetadata); + } + } + + /** + * Response for any request that the server failed to successfully perform. + * It is used internally by the transport layers to format errors for + * transport over the wire. Thus, {@link Service#apply} will never return + * an ErrorResponse. + */ + public class ErrorResponse extends Response { + private static final FieldDescriptor ERROR_MESSAGE_DESCRIPTOR = Responses.ErrorResponse + .getDescriptor().findFieldByNumber( + Responses.ErrorResponse.ERROR_MESSAGE_FIELD_NUMBER); + private static final FieldDescriptor SQL_DESCRIPTOR = Responses.ErrorResponse + .getDescriptor().findFieldByNumber( + Responses.ErrorResponse.SQL_STATE_FIELD_NUMBER); + private static final FieldDescriptor SEVERITY_DESCRIPTOR = Responses.ErrorResponse + .getDescriptor().findFieldByNumber( + Responses.ErrorResponse.SEVERITY_FIELD_NUMBER); + private static final FieldDescriptor METADATA_DESCRIPTOR = Responses.ErrorResponse + .getDescriptor().findFieldByNumber( + Responses.ErrorResponse.METADATA_FIELD_NUMBER); + + public static final int UNKNOWN_ERROR_CODE = -1; + public static final int MISSING_CONNECTION_ERROR_CODE = 1; + + public static final String UNKNOWN_SQL_STATE = "00000"; + + public final List<String> exceptions; + public final String errorMessage; + public final int errorCode; + public final String sqlState; + public final AvaticaSeverity severity; + public final RpcMetadataResponse rpcMetadata; + + ErrorResponse() { + exceptions = Collections.singletonList("Unhandled exception"); + errorMessage = "Unknown message"; + errorCode = -1; + sqlState = UNKNOWN_SQL_STATE; + severity = AvaticaSeverity.UNKNOWN; + rpcMetadata = null; + } + + @JsonCreator + public ErrorResponse(@JsonProperty("exceptions") List<String> exceptions, + @JsonProperty("errorMessage") String errorMessage, + @JsonProperty("errorCode") int errorCode, + @JsonProperty("sqlState") String sqlState, + @JsonProperty("severity") AvaticaSeverity severity, + @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) { + this.exceptions = exceptions; + this.errorMessage = errorMessage; + this.errorCode = errorCode; + this.sqlState = sqlState; + this.severity = severity; + this.rpcMetadata = rpcMetadata; + } + + protected ErrorResponse(Exception e, String errorMessage, int code, String sqlState, + AvaticaSeverity severity, RpcMetadataResponse rpcMetadata) { + this(errorMessage, code, sqlState, severity, toStackTraces(e), rpcMetadata); + } + + protected ErrorResponse(String errorMessage, int code, String sqlState, + AvaticaSeverity severity, List<String> exceptions, RpcMetadataResponse rpcMetadata) { + this.exceptions = exceptions; + this.errorMessage = errorMessage; + this.errorCode = code; + this.sqlState = sqlState; + this.severity = severity; + this.rpcMetadata = rpcMetadata; + } + + static List<String> toStackTraces(Exception e) { + List<String> stackTraces = new ArrayList<>(); + stackTraces.add(toString(e)); + if (e instanceof SQLException) { + SQLException next = ((SQLException) e).getNextException(); + while (null != next) { + stackTraces.add(toString(next)); + next = next.getNextException(); + } + } + return stackTraces; + } + + static String toString(Exception e) { + //noinspection ThrowableResultOfMethodCallIgnored + Objects.requireNonNull(e); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + } + + @Override ErrorResponse deserialize(Message genericMsg) { + final Responses.ErrorResponse msg = ProtobufService.castProtobufMessage(genericMsg, + Responses.ErrorResponse.class); + List<String> exceptions = null; + if (msg.getHasExceptions()) { + exceptions = msg.getExceptionsList(); + } + + String errorMessage = null; + if (msg.hasField(ERROR_MESSAGE_DESCRIPTOR)) { + errorMessage = msg.getErrorMessage(); + } + + String sqlState = null; + if (msg.hasField(SQL_DESCRIPTOR)) { + sqlState = msg.getSqlState(); + } + + AvaticaSeverity severity = null; + if (msg.hasField(SEVERITY_DESCRIPTOR)) { + severity = AvaticaSeverity.fromProto(msg.getSeverity()); + } + + RpcMetadataResponse metadata = null; + if (msg.hasField(METADATA_DESCRIPTOR)) { + metadata = RpcMetadataResponse.fromProto(msg.getMetadata()); + } + + return new ErrorResponse(exceptions, errorMessage, msg.getErrorCode(), sqlState, severity, + metadata); + } + + @Override Responses.ErrorResponse serialize() { + Responses.ErrorResponse.Builder builder = Responses.ErrorResponse.newBuilder(); + + if (null != rpcMetadata) { + builder.setMetadata(rpcMetadata.serialize()); + } + + if (null != exceptions) { + builder.setHasExceptions(true); + builder.addAllExceptions(exceptions); + } else { + builder.setHasExceptions(false); + } + + if (null != errorMessage) { + builder.setErrorMessage(errorMessage); + } + + if (null != sqlState) { + builder.setSqlState(sqlState); + } + + if (null != severity) { + builder.setSeverity(severity.toProto()); + } + + return builder.setErrorCode(errorCode).build(); + } + + @Override public String toString() { + StringBuilder sb = new StringBuilder(32); + sb.append("ErrorResponse[errorCode=").append(errorCode) + .append(", sqlState=").append(sqlState) + .append(", severity=").append(severity) + .append(", errorMessage=").append(errorMessage) + .append(", exceptions=").append(exceptions); + return sb.toString(); + } + + @Override public int hashCode() { + int result = 1; + result = p(result, exceptions); + result = p(result, errorMessage); + result = p(result, errorCode); + result = p(result, sqlState); + result = p(result, severity); + result = p(result, rpcMetadata); + return result; + } + + @Override public boolean equals(Object o) { + return this == o + || o instanceof ErrorResponse + && errorCode == ((ErrorResponse) o).errorCode + && severity == ((ErrorResponse) o).severity + && Objects.equals(exceptions, ((ErrorResponse) o).exceptions) + && Objects.equals(errorMessage, ((ErrorResponse) o).errorMessage) + && Objects.equals(sqlState, ((ErrorResponse) o).sqlState) + && Objects.equals(rpcMetadata, ((ErrorResponse) o).rpcMetadata); + } + + public AvaticaClientRuntimeException toException() { + return new AvaticaClientRuntimeException("Remote driver error: " + errorMessage, errorCode, + sqlState, severity, exceptions, rpcMetadata); + } + } + + /** + * Request for {@link Service#apply(SyncResultsRequest)} + */ + class SyncResultsRequest extends Request { + private static final FieldDescriptor CONNECTION_ID_DESCRIPTOR = Requests.SyncResultsRequest + .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.CONNECTION_ID_FIELD_NUMBER); + private static final FieldDescriptor STATEMENT_ID_DESCRIPTOR = Requests.SyncResultsRequest + .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.STATEMENT_ID_FIELD_NUMBER); + private static final FieldDescriptor STATE_DESCRIPTOR = Requests.SyncResultsRequest + .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.STATE_FIELD_NUMBER); + private static final FieldDescriptor OFFSET_DESCRIPTOR = Requests.SyncResultsRequest + .getDescriptor().findFieldByNumber(Requests.SyncResultsRequest.OFFSET_FIELD_NUMBER); + public final String connectionId; + public final int statementId; + public final QueryState state; + public final long offset; + + SyncResultsRequest() { + this.connectionId = null; + this.statementId = 0; + this.state = null; + this.offset = 0L; + } + + public SyncResultsRequest(@JsonProperty("connectionId") String connectionId, + @JsonProperty("statementId") int statementId, @JsonProperty("state") QueryState state, + @JsonProperty("offset") long offset) { + this.connectionId = connectionId; + this.statementId = statementId; + this.state = state; + this.offset = offset; + } + + SyncResultsResponse accept(Service service) { + return service.apply(this); + } + + Request deserialize(Message genericMsg) { + final Requests.SyncResultsRequest msg = ProtobufService.castProtobufMessage(genericMsg, + Requests.SyncResultsRequest.class); + + String connectionId = null; + if (msg.hasField(CONNECTION_ID_DESCRIPTOR)) { + connectionId = msg.getConnectionId(); + } + + int statementId = 0; + if (msg.hasField(STATEMENT_ID_DESCRIPTOR)) { + statementId = msg.getStatementId(); + } + + Common.QueryState state = null; + if (msg.hasField(STATE_DESCRIPTOR)) { + state = msg.getState(); + } + + long offset = 0; + if (msg.hasField(OFFSET_DESCRIPTOR)) { + offset = msg.getOffset(); + } + + return new SyncResultsRequest(connectionId, statementId, + null == state ? null : QueryState.fromProto(msg.getState()), offset); + } + + Requests.SyncResultsRequest serialize() { + Requests.SyncResultsRequest.Builder builder = Requests.SyncResultsRequest.newBuilder(); + + if (null != connectionId) { + builder.setConnectionId(connectionId); + } + + if (null != state) { + builder.setState(state.toProto()); + }
<TRUNCATED>
