com.nabla.wapp.server.database.SqlInsert.java Source code

Java tutorial

Introduction

Here is the source code for com.nabla.wapp.server.database.SqlInsert.java

Source

/**
* Copyright 2012 nabla
*
* 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.nabla.wapp.server.database;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.nabla.wapp.server.general.Assert;
import com.nabla.wapp.shared.database.IRecordField;
import com.nabla.wapp.shared.database.IRecordTable;
import com.nabla.wapp.shared.database.SqlInsertOptions;
import com.nabla.wapp.shared.general.ArgumentList;

public class SqlInsert<T> {

    private static final Log log = LogFactory.getLog(SqlInsert.class);
    private final String sql;
    private final List<IStatementParameter> parameters = new ArrayList<IStatementParameter>();
    private final boolean autoGeneratedKeys;

    public SqlInsert(final Class<T> recordClass, boolean autoGeneratedKeys, final SqlInsertOptions option) {
        this(recordClass, createSqlTemplate(getTable(recordClass).name(), option), autoGeneratedKeys);
    }

    public SqlInsert(final Class<T> recordClass, final SqlInsertOptions option) {
        this(recordClass, false, option);
    }

    public SqlInsert(final Class<T> recordClass, boolean autoGeneratedKeys) {
        this(recordClass, autoGeneratedKeys, SqlInsertOptions.INSERT);
    }

    public SqlInsert(final Class<T> recordClass) {
        this(recordClass, SqlInsertOptions.INSERT);
    }

    public SqlInsert(final Class<T> recordClass, final String sqlTemplate) {
        this(recordClass, sqlTemplate, false);
    }

    public SqlInsert(final Class<T> recordClass, final String sqlTemplate, boolean autoGeneratedKeys) {
        Assert.argumentNotNull(sqlTemplate);

        this.autoGeneratedKeys = autoGeneratedKeys;
        buildParameterList(recordClass);
        final ArgumentList names = new ArgumentList();
        final ArgumentList values = new ArgumentList();
        final ArgumentList updates = new ArgumentList();
        for (IStatementParameter parameter : parameters) {
            names.add(parameter.getName());
            values.add("?");
            if (!parameter.isUnique())
                updates.add(parameter.getName() + "=VALUES(" + parameter.getName() + ")");
        }
        sql = MessageFormat.format(sqlTemplate, names.toString(), values.toString(), updates.toString());
        if (log.isDebugEnabled())
            log.debug("SQL=" + sql);
    }

    public static String createSqlTemplate(final String tableName, final SqlInsertOptions option) {
        switch (option) {
        case APPEND:
            return "INSERT IGNORE INTO " + tableName + " ({0}) VALUES({1});";
        case OVERWRITE:
            return "INSERT INTO " + tableName + " ({0}) VALUES({1}) ON DUPLICATE KEY UPDATE {2};";
        case REPLACE:
            return "REPLACE INTO " + tableName + " ({0}) VALUES({1});";
        case INSERT:
        default:
            return "INSERT INTO " + tableName + " ({0}) VALUES({1});";
        }
    }

    public PreparedStatement prepareStatement(final Connection conn) throws SQLException {
        Assert.argumentNotNull(conn);

        return conn.prepareStatement(sql,
                autoGeneratedKeys ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS);
    }

    public BatchInsertStatement<T> prepareBatchStatement(final Connection conn) throws SQLException {
        return new BatchInsertStatement<T>(conn, this);
    }

    public List<IStatementParameter> getParameters() {
        return parameters;
    }

    public boolean getAutoGenerateKeys() {
        return autoGeneratedKeys;
    }

    @SuppressWarnings("unchecked")
    protected static IRecordTable getTable(final Class clazz) {
        Assert.notNull(clazz, "have you forgotten to set @IRecordTable for record " + clazz.getSimpleName());

        final IRecordTable t = (IRecordTable) clazz.getAnnotation(IRecordTable.class);
        return (t != null) ? t : getTable(clazz.getSuperclass());
    }

    protected void buildParameterList(final Class clazz) {
        if (clazz != null) {
            for (Field field : clazz.getDeclaredFields()) {
                final IRecordField definition = field.getAnnotation(IRecordField.class);
                if (definition != null)
                    parameters.add(SqlStatement.createParameter(field));
            }
            buildParameterList(clazz.getSuperclass());
        }
    }

}