ByteStringArgument.java
/*
* Copyright 2018-2019 Providence Authors
*
* 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 net.morimekta.proto.jdbi.v3.util;
import com.google.protobuf.ByteString;
import net.morimekta.proto.jdbi.MorimektaJdbiOptions.SqlType;
import net.morimekta.proto.jdbi.ProtoJdbi;
import org.jdbi.v3.core.argument.Argument;
import org.jdbi.v3.core.result.ResultSetException;
import org.jdbi.v3.core.statement.StatementContext;
import java.io.StringReader;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Base64;
import java.util.Objects;
/**
* Smart mapping of message fields to SQL bound argument. It will
* map the type to whichever type is default or selected (if supported)
* for most field types.
*/
public class ByteStringArgument implements Argument {
private final ByteString value;
private final SqlType type;
/**
* Create a message field argument.
*
* @param value The argument value.
* @param type The SQL type. See {@link Types}.
*/
public ByteStringArgument(ByteString value, SqlType type) {
this.value = value;
this.type = type;
}
@Override
public String toString() {
return getClass().getSimpleName() +
"{@type=" + type + "(" + ProtoJdbi.getColumnType(type) + "); " +
Base64.getEncoder().encodeToString(value.toByteArray()) + "}";
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ByteStringArgument)) {
return false;
}
ByteStringArgument other = (ByteStringArgument) o;
return Objects.equals(value, other.value) &&
type == other.type;
}
@Override
public int hashCode() {
return Objects.hash(getClass(), value, type);
}
@Override
public void apply(int position, PreparedStatement statement, StatementContext ctx) throws SQLException {
switch (type) {
case BINARY:
case VARBINARY:
case LONG_VARBINARY:
statement.setBytes(position, value.toByteArray());
break;
case BLOB: {
statement.setBlob(position, value.newInput());
break;
}
case CHAR:
case NCHAR:
case VARCHAR:
case NVARCHAR:
case LONG_VARCHAR:
case LONG_NVARCHAR: {
statement.setString(position, ENCODER.encodeToString(value.toByteArray()));
break;
}
case CLOB: {
var data = ENCODER.encodeToString(value.toByteArray());
statement.setClob(position, new StringReader(data));
break;
}
default:
throw new ResultSetException(
"Unsupported type " + type + " for ByteString", null, ctx);
}
}
private static final Base64.Encoder ENCODER = Base64.getEncoder();
}