All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.topicus.jdbc.shaded.com.google.cloud.spanner.Struct Maven / Gradle / Ivy

There is a newer version: 1.1.6
Show newest version
/*
 * Copyright 2017 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nl.topicus.jdbc.shaded.com.google.cloud.spanner;

import static nl.topicus.jdbc.shaded.com.google.common.base.Preconditions.checkNotNull;
import static nl.topicus.jdbc.shaded.com.google.common.base.Preconditions.checkState;

import nl.topicus.jdbc.shaded.com.google.cloud.ByteArray;
import nl.topicus.jdbc.shaded.com.google.cloud.Date;
import nl.topicus.jdbc.shaded.com.google.cloud.Timestamp;
import nl.topicus.jdbc.shaded.com.google.common.collect.ImmutableList;
import nl.topicus.jdbc.shaded.com.google.common.primitives.Booleans;
import nl.topicus.jdbc.shaded.com.google.common.primitives.Doubles;
import nl.topicus.jdbc.shaded.com.google.common.primitives.Longs;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import nl.topicus.jdbc.shaded.javax.annotation.Nullable;
import nl.topicus.jdbc.shaded.javax.annotation.concurrent.Immutable;

/**
 * Represents a value of {@link Type.Code#STRUCT}. Such values are a tuple of named and typed
 * columns, where individual columns may be null. Individual rows from a read or query operation can
 * be considered as structs; {@link ResultSet#getCurrentRowAsStruct()} allows an immutable struct to
 * be created from the row that the result set is currently positioned over.
 *
 * 

{@code Struct} instances are immutable. */ @Immutable public abstract class Struct extends AbstractStructReader implements Serializable { // Only implementations within the package are allowed. Struct() {} /** * Returns a builder for creating a {@code Struct} instance. This is intended mainly for test * purposes: the library implementation is typically responsible for creating {@code Struct} * instances. */ public static Builder newBuilder() { return new Builder(); } /** Builder for {@code Struct} instances. */ public static final class Builder { private final List types = new ArrayList<>(); private final List values = new ArrayList<>(); private final ValueBinder binder; private String currentField; private Builder() { this.binder = new ValueBinder() { @Override Builder handle(Value value) { checkBindingInProgress(true); addInternal(currentField, value); currentField = null; return Builder.this; } }; } /** Returns a binder to set the value of a new field in the struct named {@code fieldName}. */ public ValueBinder set(String fieldName) { checkBindingInProgress(false); currentField = checkNotNull(fieldName); return binder; } /** Adds a new field named {@code fieldName} with the given value. */ public Builder add(String fieldName, Value value) { checkBindingInProgress(false); addInternal(fieldName, value); return this; } /** * Adds a new field of type {@code ARRAY>} named {@code fieldName} with the * given element values. {@code elements} may be null, as may any member of {@code elements}. * All non-null members of {@code elements} must be of type {@code STRUCT} */ public Builder add( String fieldName, Iterable fieldTypes, @Nullable Iterable elements) { return add(fieldName, Value.structArray(fieldTypes, elements)); } public Struct build() { checkBindingInProgress(false); return new ValueListStruct(types, values); } private void addInternal(String fieldName, Value value) { types.add(Type.StructField.of(fieldName, value.getType())); values.add(value); } private void checkBindingInProgress(boolean expectInProgress) { if (expectInProgress) { checkState(currentField != null, "No binding currently active"); } else if (currentField != null) { throw new IllegalStateException("Incomplete binding for column " + currentField); } } } /** Default implementation for test value structs produced by {@link Builder}. */ private static class ValueListStruct extends Struct { private final Type type; private final List values; private ValueListStruct(List types, List values) { this.type = Type.struct(types); this.values = ImmutableList.copyOf(values); } @Override protected boolean getBooleanInternal(int columnIndex) { return values.get(columnIndex).getBool(); } @Override protected long getLongInternal(int columnIndex) { return values.get(columnIndex).getInt64(); } @Override protected double getDoubleInternal(int columnIndex) { return values.get(columnIndex).getFloat64(); } @Override protected String getStringInternal(int columnIndex) { return values.get(columnIndex).getString(); } @Override protected ByteArray getBytesInternal(int columnIndex) { return values.get(columnIndex).getBytes(); } @Override protected Timestamp getTimestampInternal(int columnIndex) { return values.get(columnIndex).getTimestamp(); } @Override protected Date getDateInternal(int columnIndex) { return values.get(columnIndex).getDate(); } @Override protected boolean[] getBooleanArrayInternal(int columnIndex) { return Booleans.toArray(getBooleanListInternal(columnIndex)); } @Override protected List getBooleanListInternal(int columnIndex) { return values.get(columnIndex).getBoolArray(); } @Override protected long[] getLongArrayInternal(int columnIndex) { return Longs.toArray(getLongListInternal(columnIndex)); } @Override protected List getLongListInternal(int columnIndex) { return values.get(columnIndex).getInt64Array(); } @Override protected double[] getDoubleArrayInternal(int columnIndex) { return Doubles.toArray(getDoubleListInternal(columnIndex)); } @Override protected List getDoubleListInternal(int columnIndex) { return values.get(columnIndex).getFloat64Array(); } @Override protected List getStringListInternal(int columnIndex) { return values.get(columnIndex).getStringArray(); } @Override protected List getBytesListInternal(int columnIndex) { return values.get(columnIndex).getBytesArray(); } @Override protected List getTimestampListInternal(int columnIndex) { return values.get(columnIndex).getTimestampArray(); } @Override protected List getDateListInternal(int columnIndex) { return values.get(columnIndex).getDateArray(); } @Override protected List getStructListInternal(int columnIndex) { return values.get(columnIndex).getStructArray(); } @Override public Type getType() { return type; } @Override public boolean isNull(int columnIndex) { return values.get(columnIndex).isNull(); } @Override public String toString() { // TODO(user): Consider pulling a generic toString() up to Struct. return values.toString(); } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Struct)) { return false; } Struct that = (Struct) o; if (!getType().equals(that.getType())) { return false; } for (int i = 0; i < getColumnCount(); ++i) { if (!Objects.equals(getAsObject(i), that.getAsObject(i))) { return false; } } return true; } @Override public int hashCode() { int result = getType().hashCode(); for (int i = 0; i < getColumnCount(); ++i) { result = 31 * result + Objects.hashCode(getAsObject(i)); } return result; } private Object getAsObject(int columnIndex) { Type type = getColumnType(columnIndex); if (isNull(columnIndex)) { return null; } switch (type.getCode()) { case BOOL: return getBooleanInternal(columnIndex); case INT64: return getLongInternal(columnIndex); case FLOAT64: return getDoubleInternal(columnIndex); case STRING: return getStringInternal(columnIndex); case BYTES: return getBytesInternal(columnIndex); case TIMESTAMP: return getTimestampInternal(columnIndex); case DATE: return getDateInternal(columnIndex); case ARRAY: switch (type.getArrayElementType().getCode()) { case BOOL: return getBooleanListInternal(columnIndex); case INT64: return getLongListInternal(columnIndex); case FLOAT64: return getDoubleListInternal(columnIndex); case STRING: return getStringListInternal(columnIndex); case BYTES: return getBytesListInternal(columnIndex); case TIMESTAMP: return getTimestampListInternal(columnIndex); case DATE: return getDateListInternal(columnIndex); case STRUCT: return getStructListInternal(columnIndex); default: throw new AssertionError("Invalid type " + type); } default: throw new AssertionError("Invalid type " + type); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy