| /* |
| * 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.proto.Common; |
| |
| import com.fasterxml.jackson.annotation.JsonCreator; |
| import com.fasterxml.jackson.annotation.JsonProperty; |
| import com.google.protobuf.Descriptors.FieldDescriptor; |
| |
| import java.sql.Connection; |
| import java.sql.SQLException; |
| import java.util.Objects; |
| |
| /** Concrete implementation of {@link Meta.ConnectionProperties}. Provides additional state |
| * tracking to enable {@code RemoteMeta} to lazily push changes up to a query server. |
| * |
| * <p>{@code Meta} instances should probably hold authority on the {@code isDirty} |
| * flag because {@code AvaticaConnection} instances have no way of knowing if they're local or |
| * remote. |
| */ |
| public class ConnectionPropertiesImpl implements Meta.ConnectionProperties { |
| private static final FieldDescriptor CATALOG_DESCRIPTOR = Common.ConnectionProperties |
| .getDescriptor().findFieldByNumber(Common.ConnectionProperties.CATALOG_FIELD_NUMBER); |
| private static final FieldDescriptor SCHEMA_DESCRIPTOR = Common.ConnectionProperties |
| .getDescriptor().findFieldByNumber(Common.ConnectionProperties.SCHEMA_FIELD_NUMBER); |
| private static final FieldDescriptor TRANSACTION_ISOLATION_DESCRIPTOR = Common |
| .ConnectionProperties.getDescriptor().findFieldByNumber( |
| Common.ConnectionProperties.TRANSACTION_ISOLATION_FIELD_NUMBER); |
| |
| private boolean isDirty = false; |
| private Boolean autoCommit; |
| private Boolean readOnly; |
| private Integer transactionIsolation; |
| private String catalog; |
| private String schema; |
| |
| // TODO: replace with Meta.ConnectionProperties$EMPTY instance? |
| public ConnectionPropertiesImpl() {} |
| |
| public ConnectionPropertiesImpl(Connection conn) throws SQLException { |
| this(conn.getAutoCommit(), conn.isReadOnly(), conn.getTransactionIsolation(), |
| conn.getCatalog(), conn.getSchema()); |
| } |
| |
| @JsonCreator |
| public ConnectionPropertiesImpl( |
| @JsonProperty("autoCommit") Boolean autoCommit, |
| @JsonProperty("readOnly") Boolean readOnly, |
| @JsonProperty("transactionIsolation") Integer transactionIsolation, |
| @JsonProperty("catalog") String catalog, |
| @JsonProperty("schema") String schema) { |
| this.autoCommit = autoCommit; |
| this.readOnly = readOnly; |
| this.transactionIsolation = transactionIsolation; |
| this.catalog = catalog; |
| this.schema = schema; |
| } |
| |
| public ConnectionPropertiesImpl setDirty(boolean val) { |
| this.isDirty = val; |
| return this; |
| } |
| |
| public boolean isDirty() { |
| return this.isDirty; |
| } |
| |
| @Override public boolean isEmpty() { |
| return autoCommit == null && readOnly == null && transactionIsolation == null |
| && catalog == null && schema == null; |
| } |
| |
| /** Overwrites fields in {@code this} with any non-null fields in {@code that}. Sets |
| * {@code isDirty} if any fields are changed. |
| * |
| * @return {@code this} |
| */ |
| @Override public ConnectionPropertiesImpl merge(Meta.ConnectionProperties that) { |
| if (this == that) { |
| return this; |
| } |
| if (that.isAutoCommit() != null && !Objects.equals(this.autoCommit, that.isAutoCommit())) { |
| this.autoCommit = that.isAutoCommit(); |
| this.isDirty = true; |
| } |
| if (that.isReadOnly() != null && !Objects.equals(this.readOnly, that.isReadOnly())) { |
| this.readOnly = that.isReadOnly(); |
| this.isDirty = true; |
| } |
| if (that.getTransactionIsolation() != null |
| && !Objects.equals(this.transactionIsolation, that.getTransactionIsolation())) { |
| this.transactionIsolation = that.getTransactionIsolation(); |
| this.isDirty = true; |
| } |
| if (that.getCatalog() != null && !that.getCatalog().equalsIgnoreCase(this.catalog)) { |
| this.catalog = that.getCatalog(); |
| this.isDirty = true; |
| } |
| if (that.getSchema() != null && !that.getSchema().equalsIgnoreCase(this.schema)) { |
| this.schema = that.getSchema(); |
| this.isDirty = true; |
| } |
| return this; |
| } |
| |
| /** Sets {@code autoCommit} status and flag as dirty. |
| * |
| * @return {@code this} |
| */ |
| @Override public Meta.ConnectionProperties setAutoCommit(boolean val) { |
| this.autoCommit = val; |
| this.isDirty = true; |
| return this; |
| } |
| |
| @Override public Boolean isAutoCommit() { |
| return this.autoCommit; |
| } |
| |
| /** Sets {@code readOnly} status and flag as dirty. |
| * |
| * @return {@code this} |
| */ |
| @Override public Meta.ConnectionProperties setReadOnly(boolean val) { |
| this.readOnly = val; |
| this.isDirty = true; |
| return this; |
| } |
| |
| @Override public Boolean isReadOnly() { |
| return this.readOnly; |
| } |
| |
| /** Sets {@code transactionIsolation} status and flag as dirty. |
| * |
| * @return {@code this} |
| */ |
| @Override public Meta.ConnectionProperties setTransactionIsolation(int val) { |
| this.transactionIsolation = val; |
| this.isDirty = true; |
| return this; |
| } |
| |
| public Integer getTransactionIsolation() { |
| return this.transactionIsolation; |
| } |
| |
| /** Sets {@code catalog} and flag as dirty. |
| * |
| * @return {@code this} |
| */ |
| @Override public Meta.ConnectionProperties setCatalog(String val) { |
| this.catalog = val; |
| this.isDirty = true; |
| return this; |
| } |
| |
| @Override public String getCatalog() { |
| return this.catalog; |
| } |
| |
| /** Sets {@code schema} and flag as dirty. |
| * |
| * @return {@code this} |
| */ |
| @Override public Meta.ConnectionProperties setSchema(String val) { |
| this.schema = val; |
| this.isDirty = true; |
| return this; |
| } |
| |
| public String getSchema() { |
| return this.schema; |
| } |
| |
| @Override public int hashCode() { |
| return Objects.hash(autoCommit, catalog, isDirty, readOnly, schema, |
| transactionIsolation); |
| } |
| |
| @Override public boolean equals(Object o) { |
| return o == this |
| || o instanceof ConnectionPropertiesImpl |
| && Objects.equals(autoCommit, ((ConnectionPropertiesImpl) o).autoCommit) |
| && Objects.equals(catalog, ((ConnectionPropertiesImpl) o).catalog) |
| && isDirty == ((ConnectionPropertiesImpl) o).isDirty |
| && Objects.equals(readOnly, ((ConnectionPropertiesImpl) o).readOnly) |
| && Objects.equals(schema, ((ConnectionPropertiesImpl) o).schema) |
| && Objects.equals(transactionIsolation, |
| ((ConnectionPropertiesImpl) o).transactionIsolation); |
| } |
| |
| public Common.ConnectionProperties toProto() { |
| Common.ConnectionProperties.Builder builder = Common.ConnectionProperties.newBuilder(); |
| |
| if (null != autoCommit) { |
| builder.setHasAutoCommit(true); |
| builder.setAutoCommit(autoCommit.booleanValue()); |
| } else { |
| // Be explicit to avoid default value confusion |
| builder.setHasAutoCommit(false); |
| } |
| |
| if (null != catalog) { |
| builder.setCatalog(catalog); |
| } |
| |
| builder.setIsDirty(isDirty); |
| |
| if (null != readOnly) { |
| builder.setHasReadOnly(true); |
| builder.setReadOnly(readOnly.booleanValue()); |
| } else { |
| // Be explicit to avoid default value confusion |
| builder.setHasReadOnly(false); |
| } |
| |
| if (null != schema) { |
| builder.setSchema(schema); |
| } |
| |
| if (null != transactionIsolation) { |
| builder.setTransactionIsolation(transactionIsolation.intValue()); |
| } |
| |
| return builder.build(); |
| } |
| |
| public static ConnectionPropertiesImpl fromProto(Common.ConnectionProperties proto) { |
| String catalog = null; |
| if (proto.hasField(CATALOG_DESCRIPTOR)) { |
| catalog = proto.getCatalog(); |
| } |
| |
| String schema = null; |
| if (proto.hasField(SCHEMA_DESCRIPTOR)) { |
| schema = proto.getSchema(); |
| } |
| |
| Boolean autoCommit = null; |
| if (proto.getHasAutoCommit()) { |
| autoCommit = Boolean.valueOf(proto.getAutoCommit()); |
| } |
| |
| Boolean readOnly = null; |
| if (proto.getHasReadOnly()) { |
| readOnly = Boolean.valueOf(proto.getReadOnly()); |
| } |
| |
| Integer transactionIsolation = null; |
| if (proto.hasField(TRANSACTION_ISOLATION_DESCRIPTOR)) { |
| transactionIsolation = Integer.valueOf(proto.getTransactionIsolation()); |
| } |
| |
| ConnectionPropertiesImpl impl = new ConnectionPropertiesImpl(autoCommit, readOnly, |
| transactionIsolation, catalog, schema); |
| |
| impl.setDirty(proto.getIsDirty()); |
| |
| return impl; |
| } |
| } |
| |
| // End ConnectionPropertiesImpl.java |