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

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

The 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.entityreader.DBSupportedTypes;
import com.wizarius.orm.database.entityreader.WizEntityManager;
import com.wizarius.orm.database.handlers.WritableHandler;
import lombok.extern.slf4j.Slf4j;

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

/**
 * @author Vladyslav Shyshkin on 21.01.17.
 */
@Slf4j
public class WizDBUpdate extends WizAbstractWhereAction> implements IDBUpdate {
    public WizDBUpdate(DBConnectionPool pool, DBParsedFieldsList fields) {
        super(pool, fields);
    }

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

    /**
     * Execute delete 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 delete
     * @param connection connection to database
     * @throws DBException on unable to delete
     */
    @Override
    public void execute(Entity entity, DBConnection connection) throws DBException {
        try {
            PreparedStatement statement = toPreparedSQLQuery(entity, connection);
            log.trace("Execute delete query: " + statement.toString());
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new DBException("Unable to execute query " + e.getMessage(), e);
        }
    }

    /**
     * Execute custom update query
     *
     * @param values values map where key = db field name, value = field value
     * @throws DBException on unable to execute query
     */
    @Override
    public void executeCustom(Map values) throws DBException {
        try (DBConnection connection = pool.getConnection()) {
            executeCustom(values, connection);
        }
    }

    /**
     * Execute custom update 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 values     values map where key = db field name, value = field value
     * @param connection database connection
     * @throws DBException on unable to execute query
     */
    @Override
    public void executeCustom(Map values, DBConnection connection) throws DBException {
        String query = buildCustomPreparedStatement(values) + "\n" + whereQueryBuilder.getWhereQuery();
        try {
            PreparedStatement statement = connection.createPrepareStatement(query);
            AtomicInteger index = new AtomicInteger(1);
            // setup field
            for (Map.Entry entry : values.entrySet()) {
                DBParsedField field = fields.getFieldByDBFieldName(entry.getKey());
                setupIndexValue(statement, index, field, entry.getValue());
            }
            // setup where values
            whereQueryBuilder.setupWhereValues(index, statement);
            statement.executeUpdate();
        } catch (SQLException e) {
            throw new DBException("Unable to build prepared statement query. " + e.getMessage(), e);
        }
    }

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

    /**
     * Convert values map to prepared statement cause
     *
     * @param values map where key = db field, value = value to SET
     * @return prepared statement
     * @throws DBException on invalid db field
     */
    private String buildCustomPreparedStatement(Map values) throws DBException {
        StringBuilder sb = new StringBuilder();
        sb.append("UPDATE ").append(getTableName()).append(" SET ");
        //build delete into query
        for (Map.Entry entry : values.entrySet()) {
            DBParsedField field = fields.getFieldByDBFieldName(entry.getKey());
            if (field == null) {
                throw new DBException("Unable to find field in object where field name = " + entry.getKey());
            }
            sb.append(field.getDbFieldName()).append(" = ").append("?").append(", ");
        }
        sb.setLength(sb.length() - 2);
        return sb.toString();
    }

    /**
     * Setup index value
     *
     * @param statement statement
     * @param index     current index
     * @param value     value to set to prepare statement
     * @throws DBException on unable to set prepared statement value
     */
    private void setupIndexValue(PreparedStatement statement, AtomicInteger index, DBParsedField field, Object value) throws DBException {
        DBSupportedTypes supportedType = WizEntityManager.javaTypeToDBType(field.getClazz());
        WritableHandler handlerByType = writableHandlers.getHandlerByType(supportedType);
        try {
            handlerByType.set(value, index.getAndIncrement(), statement);
        } catch (SQLException e) {
            throw new DBException("Unable to setup value to prepared statement", e);
        }
    }

    /**
     * Build prepare statement query
     *
     * @return prepare statement query
     */
    private String buildPrepareStatementQuery() {
        StringBuilder sb = new StringBuilder();
        sb.append("UPDATE ").append(getTableName()).append(" SET ");
        //build delete into query
        for (DBParsedField entry : fields) {
            if (entry.isJoinField() || entry.isAutoincrement()) {
                continue;
            }
            sb.append(entry.getDbFieldName()).append(" = ").append("?").append(", ");
        }
        sb.setLength(sb.length() - 2);
        return sb.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(Entity entity, DBConnection connection) throws DBException {
        DBParsedField primaryKey = fields.getPrimaryKey();
        if (primaryKey == null) {
            throw new DBException("ID must be present");
        }
        try {
            Field field = primaryKey.getField();
            field.setAccessible(true);
            where(primaryKey.getDbFieldName(), field.get(entity));
        } catch (IllegalAccessException e) {
            throw new DBException("Unable to get primary key value");
        }
        try {
            String query = buildPrepareStatementQuery() + "\n" + whereQueryBuilder.getWhereQuery();
            PreparedStatement statement = connection.createPrepareStatement(query);
            AtomicInteger index = new AtomicInteger(1);
            fieldsPrepareStatementQueryBuilder.setupPreparedStatementValues(index, entity, statement);
            whereQueryBuilder.setupWhereValues(index, statement);
            return statement;
        } catch (SQLException e) {
            throw new DBException("Unable to build prepared statement query. " + e.getMessage(), e);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy