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

com.wizarius.orm.database.actions.WizDBInsert Maven / Gradle / Ivy

There is a newer version: 0.0.27.6
Show newest version
package com.wizarius.orm.database.actions;

import com.wizarius.orm.database.DBException;
import com.wizarius.orm.database.connection.DBConnection;
import com.wizarius.orm.database.connection.DBConnectionPool;
import com.wizarius.orm.database.entityreader.DBParsedField;
import com.wizarius.orm.database.entityreader.DBParsedFieldsList;
import com.wizarius.orm.database.handlers.ReadableHandler;
import com.wizarius.orm.utils.WizariusArrayPartition;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Vladyslav Shyshkin on 21.01.17.
 */
@Slf4j
public class WizDBInsert extends WizAbstractDBAction implements IDBInsert {
    private final String preparedStatementQuery;

    public WizDBInsert(DBConnectionPool pool, DBParsedFieldsList fieldsMap) {
        super(pool, fieldsMap);
        this.preparedStatementQuery = buildPrepareStatementQuery(1);
    }

    /**
     * Build prepare statement query
     *
     * @return prepare statement query
     */
    private String buildPrepareStatementQuery(int valueCount) {
        StringBuilder sb = new StringBuilder();
        sb.append(" INSERT INTO ").append(fields.getTableName()).append("(");
        //build insert into query
        for (DBParsedField entry : fields) {
            if (entry.isJoinField()) {
                continue;
            }
            if (!entry.isAutoincrement()) {
                sb.append(entry.getDbFieldName()).append(",");
            }
        }
        sb.setLength(sb.length() - 1);
        sb.append(")").append(" VALUES ");
        for (int i = 0; i < valueCount; i++) {
            buildValuesPrepareString(sb);
            sb.append(",");
        }
        sb.setLength(sb.length() - 1);
        return sb.toString();
    }

    /**
     * Build values string and add to string builder like (?,?,?,?)
     *
     * @param sb string builder to add values
     */
    private void buildValuesPrepareString(StringBuilder sb) {
        sb.append("(");
        for (DBParsedField entry : fields) {
            if (entry.isJoinField()) {
                continue;
            }
            if (!entry.isAutoincrement()) {
                sb.append("?").append(",");
            }
        }
        sb.setLength(sb.length() - 1);
        sb.append(")");
    }

    /**
     * Check array
     *
     * @param entities list of entities
     * @throws DBException on incorrect arrray
     */
    private void checkArray(List entities) throws DBException {
        if (entities == null || entities.size() == 0) {
            throw new DBException("Unable to save empty array");
        }
        for (Entity entity : entities) {
            if (entity == null) {
                throw new DBException("Unable to save NULL object in array");
            }
        }
    }

    /**
     * Execute insert query
     *
     * @param entity entity to insert
     * @throws DBException on unable to insert
     */
    @Override
    public void execute(Entity entity) throws DBException {
        try (DBConnection connection = pool.getConnection()) {
            execute(entity, connection);
        }
    }

    /**
     * Execute insert query
     * If connection is presented, it is assumed that the user himself wants to manage the connection
     * The connection will not be automatically closed after the request
     *
     * @param entity     entity to insert
     * @param connection connection to database
     * @throws DBException on unable to insert
     */
    @Override
    public void execute(Entity entity, DBConnection connection) throws DBException {
        try {
            PreparedStatement statement = toPreparedSQLQuery(connection, entity);
            statement.executeUpdate();
            ResultSet rs = statement.getGeneratedKeys();
            if (rs.next()) {
                setupEntityID(entity, rs);
            }
        } catch (SQLException e) {
            throw new DBException("Unable to execute query " + e.getMessage(), e);
        }
    }

    /**
     * Execute multiple insert query
     *
     * @param entities       list of entities
     * @param truncateLength max items in one query
     * @throws DBException on unable to insert
     */
    @Override
    public void execute(List entities, int truncateLength) throws DBException {
        try (DBConnection connection = pool.getConnection()) {
            connection.startTransaction();
            execute(entities, connection, truncateLength);
            connection.commitTransaction();
        } catch (SQLException e) {
            // do not need to do rollback, it will happen in the close method
            throw new DBException("Unable to start or commit transaction. " + e.getMessage(), e);
        }
    }

    /**
     * Execute multiple insert query
     * If connection is presented, it is assumed that the user himself wants to manage the connection
     * The connection will not be automatically closed after the request
     *
     * @param entities       list of entities
     * @param connection     connection to database
     * @param truncateLength max items in one query
     * @throws DBException on unable to insert
     */
    @Override
    public void execute(List entities, DBConnection connection, int truncateLength) throws DBException {
        checkArray(entities);
        WizariusArrayPartition partitions = WizariusArrayPartition.ofSize(entities, truncateLength);
        try {
            for (List partition : partitions) {
                String insertQuery = buildPrepareStatementQuery(partition.size());
                PreparedStatement statement = connection.createPrepareStatement(insertQuery);
                AtomicInteger index = new AtomicInteger(1);
                for (Entity entity : partition) {
                    fieldsPrepareStatementQueryBuilder.setupPreparedStatementValues(index, entity, statement);
                }
                statement.executeUpdate();
                ResultSet rs = statement.getGeneratedKeys();
                int ind = 0;
                while (rs.next()) {
                    setupEntityID(partition.get(ind++), rs);
                }
            }
        } catch (SQLException e) {
            throw new DBException("Unable to execute query. " + e.getMessage(), e);
        }
    }

    /**
     * Returns sql query with all parameters and where conditions
     *
     * @return query for execution
     * @throws DBException unable to build query
     */
    @Override
    public String toSQLQuery(Entity entity) throws DBException {
        try (DBConnection session = pool.getConnection()) {
            return toPreparedSQLQuery(session, entity).toString();
        }
    }

    /**
     * Get sql query with all parameters and where conditions
     *
     * @param connection jdbc connection
     * @return prepared sql query
     * @throws DBException on unable to build query
     */
    private PreparedStatement toPreparedSQLQuery(DBConnection connection, Entity entity) throws DBException {
        try {
            PreparedStatement statement = connection.createPrepareStatement(preparedStatementQuery);
            AtomicInteger index = new AtomicInteger(1);
            fieldsPrepareStatementQueryBuilder.setupPreparedStatementValues(index, entity, statement);
            return statement;
        } catch (SQLException e) {
            throw new DBException("Unable to build prepared statement query. " + e.getMessage(), e);
        }
    }

    /**
     * Setup entity id
     *
     * @param entity    entity id
     * @param resultSet result set
     * @throws DBException on unable to setup entity id
     */
    private void setupEntityID(Entity entity, ResultSet resultSet) throws DBException {
        DBParsedField primaryKey = fields.getPrimaryKey();
        if (primaryKey != null) {
            Field field = primaryKey.getField();
            field.setAccessible(true);
            ReadableHandler handler = readableHandlers.get(primaryKey.getFieldType());
            if (handler == null) {
                throw new DBException("Unable to found handler where type = " + primaryKey.getFieldType());
            }
            try {
                handler.set(field, entity, resultSet, 1, primaryKey);
            } catch (Exception e) {
                throw new DBException("Unable to setup entity ID " + e.getMessage(), e);
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy