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

com.d3x.core.db.DatabaseMapping Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2018-2019 D3X Systems - All Rights Reserved
 *
 * 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 com.d3x.core.db;

import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Currency;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicBoolean;

import com.d3x.core.util.Option;

/**
 * A component that defines how a data type is mapped to a database for select, insert, update and delete operations.
 *
 * @param    the type for this mapping
 */
public interface DatabaseMapping {

    /**
     * Returns the data type for this mapping
     * @return  the data type
     */
    Type type();

    /**
     * The mapper to map a row in a result set to some object
     * @return  the mapper to map a row in a result set to some object
     */
    default Mapper select() {
        throw new UnsupportedOperationException("The select operation is not supported for type: " + type());
    }

    /**
     * The binder to bind arguments to a PreparedStatement for affecting inserts
     * @return binder to bind arguments to a PreparedStatement for affecting inserts
     */
    default Binder insert()  {
        throw new UnsupportedOperationException("The insert operation is not supported for type: " + type());
    }

    /**
     * The binder to bind arguments to a PreparedStatement for affecting updates
     * @return binder to bind arguments to a PreparedStatement for affecting updates
     */
    default Binder update() {
        throw new UnsupportedOperationException("The update operation is not supported for type: " + type());
    }

    /**
     * The binder to bind arguments to a PreparedStatement for affecting deletes
     * @return binder to bind arguments to a PreparedStatement for affecting deletes
     */
    default Binder delete() {
        throw new UnsupportedOperationException("The delete operation is not supported for type: " + type());
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readBoolean(ResultSet rs, int column) throws SQLException {
        var value = rs.getBoolean(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readBoolean(ResultSet rs, String column) throws SQLException {
        var value = rs.getBoolean(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readShort(ResultSet rs, int column) throws SQLException {
        var value = rs.getShort(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readShort(ResultSet rs, String column) throws SQLException {
        var value = rs.getShort(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readInt(ResultSet rs, int column) throws SQLException {
        var value = rs.getInt(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readInt(ResultSet rs, String column) throws SQLException {
        var value = rs.getInt(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readLong(ResultSet rs, int column) throws SQLException {
        var value = rs.getLong(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readLong(ResultSet rs, String column) throws SQLException {
        var value = rs.getLong(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readFloat(ResultSet rs, int column) throws SQLException {
        var value = rs.getFloat(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readFloat(ResultSet rs, String column) throws SQLException {
        var value = rs.getFloat(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readDouble(ResultSet rs, int column) throws SQLException {
        var value = rs.getDouble(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readDouble(ResultSet rs, String column) throws SQLException {
        var value = rs.getDouble(column);
        return rs.wasNull() ? Option.empty() : Option.of(value);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readString(ResultSet rs, int column) throws SQLException {
        return Option.of(rs.getString(column));
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readString(ResultSet rs, String column) throws SQLException {
        return Option.of(rs.getString(column));
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readDate(ResultSet rs, int column) throws SQLException {
        return Option.of(rs.getDate(column));
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readDate(ResultSet rs, String column) throws SQLException {
        return Option.of(rs.getDate(column));
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @param calendar  the calendar to initialize date
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readDate(ResultSet rs, int column, Calendar calendar) throws SQLException {
        return Option.of(rs.getDate(column, calendar));
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @param calendar  the calendar to initialize date
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readDate(ResultSet rs, String column, Calendar calendar) throws SQLException {
        return Option.of(rs.getDate(column, calendar));
    }


    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readLocalDate(ResultSet rs, int column) throws SQLException {
        return Option.of(rs.getDate(column)).map(Date::toLocalDate);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option readLocalDate(ResultSet rs, String column) throws SQLException {
        return Option.of(rs.getDate(column)).map(Date::toLocalDate);
    }

    /**
     * Returns an option on the value read from the ResultSet
     * @param rs        the result set to read from
     * @param column    the column to access
     * @return          the option on value
     * @throws SQLException if there is a SQL error
     */
    static Option