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

dev.miku.r2dbc.mysql.InsertSyntheticRow Maven / Gradle / Ivy

/*
 * Copyright 2018-2020 the original author or authors.
 *
 * 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 dev.miku.r2dbc.mysql;

import dev.miku.r2dbc.mysql.codec.Codecs;
import dev.miku.r2dbc.mysql.constant.DataTypes;
import io.r2dbc.spi.ColumnMetadata;
import io.r2dbc.spi.Nullability;
import io.r2dbc.spi.Row;
import io.r2dbc.spi.RowMetadata;

import java.math.BigInteger;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

import static dev.miku.r2dbc.mysql.util.AssertUtils.requireNonNull;

/**
 * An implementation of {@link Row} for support to reading last inserted ID.
 * 

* It is also an implementation of {@link RowMetadata} and {@link ColumnMetadata} for reduce redundant objects. * * @see MySqlStatement#returnGeneratedValues(String...) reading last inserted ID. */ final class InsertSyntheticRow implements Row, RowMetadata, ColumnMetadata { private final Codecs codecs; private final String keyName; private final long lastInsertId; private final ColumnNameSet nameSet; InsertSyntheticRow(Codecs codecs, String keyName, long lastInsertId) { this.codecs = requireNonNull(codecs, "codecs must not be null"); this.keyName = requireNonNull(keyName, "keyName must not be null"); // lastInsertId may be negative if key is BIGINT UNSIGNED and value overflow than signed int64. this.lastInsertId = lastInsertId; // Singleton name must be sorted. this.nameSet = new ColumnNameSet(keyName); } @Override public T get(int index, Class type) { requireNonNull(type, "type must not be null"); assertValidIndex(index); return get0(type); } @Override public T get(String name, Class type) { requireNonNull(name, "name must not be null"); requireNonNull(type, "type must not be null"); assertValidName(name); return get0(type); } @Override public Number get(int index) { assertValidIndex(index); return get0(getJavaType0()); } @Override public Number get(String name) { requireNonNull(name, "name must not be null"); assertValidName(name); return get0(getJavaType0()); } @Override public ColumnMetadata getColumnMetadata(int index) { assertValidIndex(index); return this; } @Override public ColumnMetadata getColumnMetadata(String name) { requireNonNull(name, "name must not be null"); assertValidName(name); return this; } @Override public List getColumnMetadatas() { return Collections.singletonList(this); } @Override public Set getColumnNames() { return nameSet; } @Override public Class getJavaType() { return getJavaType0(); } @Override public String getName() { return keyName; } @Override public Integer getNativeTypeMetadata() { return (int) DataTypes.BIGINT; } @Override public Nullability getNullability() { return Nullability.NON_NULL; } @Override public Integer getPrecision() { // The default precision of BIGINT is 20 return 20; } @Override public Integer getScale() { // BIGINT not support scale. return null; } private void assertValidName(String name) { if (!nameSet.contains(name)) { throw new NoSuchElementException(String.format("column name '%s' does not exist in %s", name, this.nameSet)); } } private T get0(Class type) { return codecs.decodeLastInsertId(lastInsertId, type); } private Class getJavaType0() { if (lastInsertId < 0) { // BIGINT UNSIGNED return BigInteger.class; } else { return Long.TYPE; } } private static void assertValidIndex(int index) { if (index != 0) { throw new ArrayIndexOutOfBoundsException(String.format("column index %d is invalid, total 1", index)); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy