Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.j256.ormlite.stmt.mapped;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.j256.ormlite.db.DatabaseType;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.misc.SqlExceptionUtil;
import com.j256.ormlite.support.DatabaseConnection;
import com.j256.ormlite.support.GeneratedKeyHolder;
import com.j256.ormlite.table.TableInfo;
/**
* A mapped statement for creating a new instance of an object.
*
* @author graywatson
*/
public class MappedCreate extends BaseMappedStatement {
private final String queryNextSequenceStmt;
private String dataClassName;
private MappedCreate(TableInfo tableInfo, String statement, List argFieldTypeList,
String queryNextSequenceStmt) {
super(tableInfo, statement, argFieldTypeList);
this.dataClassName = tableInfo.getDataClass().getSimpleName();
this.queryNextSequenceStmt = queryNextSequenceStmt;
}
/**
* Create an object in the database.
*/
@Override
public int insert(DatabaseConnection databaseConnection, T data) throws SQLException {
if (idField != null) {
if (idField.isGeneratedIdSequence()) {
assignSequenceId(databaseConnection, data);
// fall down to do the update below
} else if (idField.isGeneratedId()) {
// this has to do the update first then get the generated-id from callback
return createWithGeneratedId(databaseConnection, data);
} else {
// the id should have been set by the caller already
}
}
return super.insert(databaseConnection, data);
}
public static MappedCreate build(DatabaseType databaseType, TableInfo tableInfo) {
StringBuilder sb = new StringBuilder();
StringBuilder questionSb = new StringBuilder();
List argFieldTypeList = new ArrayList();
appendTableName(databaseType, sb, "INSERT INTO ", tableInfo.getTableName());
sb.append('(');
boolean first = true;
for (FieldType fieldType : tableInfo.getFieldTypes()) {
if (databaseType.isIdSequenceNeeded()) {
// we need to query for the next value from the sequence and the idField is inserted afterwards
} else if (fieldType.isGeneratedId()) {
// skip generated-id fields because they will be auto-inserted
continue;
}
if (first) {
first = false;
} else {
sb.append(",");
questionSb.append(",");
}
appendFieldColumnName(databaseType, sb, fieldType, argFieldTypeList);
questionSb.append("?");
}
sb.append(") VALUES (").append(questionSb).append(")");
FieldType idField = tableInfo.getIdField();
String queryNext = buildQueryNextSequence(databaseType, idField);
return new MappedCreate(tableInfo, sb.toString(), argFieldTypeList, queryNext);
}
private static String buildQueryNextSequence(DatabaseType databaseType, FieldType idField) {
if (idField == null) {
return null;
}
String seqName = idField.getGeneratedIdSequence();
if (seqName == null) {
return null;
} else {
StringBuilder sb = new StringBuilder();
databaseType.appendSelectNextValFromSequence(sb, seqName);
return sb.toString();
}
}
private void assignSequenceId(DatabaseConnection databaseConnection, T data) throws SQLException {
// call the query-next-sequence stmt to increment the sequence
long seqVal = databaseConnection.queryForLong(queryNextSequenceStmt);
logger.debug("queried for sequence {} using stmt: {}", seqVal, queryNextSequenceStmt);
if (seqVal == 0) {
// sanity check that it is working
throw new SQLException("Should not have returned 0 for stmt: " + queryNextSequenceStmt);
}
assignIdValue(data, seqVal, "sequence");
}
private int createWithGeneratedId(DatabaseConnection databaseConnection, T data) throws SQLException {
Object[] args = getFieldObjects(argFieldTypes, data);
try {
KeyHolder keyHolder = new KeyHolder();
// do the insert first
int retVal = databaseConnection.insert(statement, args, argSqlTypes, keyHolder);
logger.debug("create object using '{}' and {} args, changed {} rows", statement, args.length, retVal);
if (args.length > 0) {
// need to do the (Object) cast to force args to be a single object
logger.trace("create arguments: {}", (Object) args);
}
// if we created 1 row, assign the id field
if (retVal == 1) {
// assign the key returned by JDBC to the object's id field after it was inserted
Number key = keyHolder.getKey();
if (key == null) {
// may never happen but let's be careful out there
throw new SQLException("generated-id key was not set by the update call");
}
if (key.longValue() == 0L) {
// sanity check because the generated-key returned is 0 by default, may never happen
throw new SQLException("generated-id key must not be 0 value");
}
assignIdValue(data, key, "keyholder");
}
return retVal;
} catch (SQLException e) {
logger.debug("create object using '{}' and {} args, threw exception: {}", statement, args.length, e);
if (args.length > 0) {
// need to do the (Object) cast to force args to be a single object
logger.trace("create arguments: {}", (Object) args);
}
throw SqlExceptionUtil.create("Unable to run stmt on object " + data + ": " + statement, e);
}
}
private void assignIdValue(T data, Number val, String label) throws SQLException {
// better to do this in one please with consistent logging
idField.assignIdValue(data, val);
logger.debug("assigned id '{}' from {} to '{}' in {} object", val, label, idField.getFieldName(), dataClassName);
}
private class KeyHolder implements GeneratedKeyHolder {
Number key;
public Number getKey() {
return key;
}
public void addKey(Number key) throws SQLException {
if (this.key == null) {
this.key = key;
} else {
throw new SQLException("generated key has already been set to " + this.key + ", now set to " + key);
}
}
}
}