com.avaje.ebeaninternal.server.persist.Binder Maven / Gradle / Ivy
/**
* Copyright (C) 2006 Robin Bygrave
*
* This file is part of Ebean.
*
* Ebean is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* Ebean is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Ebean; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.avaje.ebeaninternal.server.persist;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.PersistenceException;
import com.avaje.ebeaninternal.api.BindParams;
import com.avaje.ebeaninternal.server.core.Message;
import com.avaje.ebeaninternal.server.type.DataBind;
import com.avaje.ebeaninternal.server.type.ScalarType;
import com.avaje.ebeaninternal.server.type.TypeManager;
/**
* Binds bean values to a PreparedStatement.
*/
public class Binder {
private static final Logger logger = Logger.getLogger(Binder.class.getName());
//private final Calendar calendar;
private final TypeManager typeManager;
/**
* Set the PreparedStatement with which to bind variables to.
*/
public Binder(TypeManager typeManager) {
this.typeManager = typeManager;
//this.calendar = new GregorianCalendar();
}
/**
* Bind the values to the Prepared Statement.
*/
public void bind(BindValues bindValues, DataBind dataBind, StringBuilder bindBuf)
throws SQLException {
String logPrefix = "";
ArrayList list = bindValues.values();
for (int i = 0; i < list.size(); i++) {
BindValues.Value bindValue = (BindValues.Value) list.get(i);
if (bindValue.isComment()) {
if (bindBuf != null) {
bindBuf.append(bindValue.getName());
if (logPrefix.equals("")) {
logPrefix = ", ";
}
}
} else {
Object val = bindValue.getValue();
int dt = bindValue.getDbType();
bindObject(dataBind, val, dt);
if (bindBuf != null) {
bindBuf.append(logPrefix);
if (logPrefix.equals("")) {
logPrefix = ", ";
}
bindBuf.append(bindValue.getName());
bindBuf.append("=");
if (isLob(dt)) {
bindBuf.append("[LOB]");
} else {
bindBuf.append(String.valueOf(val));
}
}
}
}
}
/**
* Bind the list of positionedParameters in BindParams.
*/
public String bind(BindParams bindParams, DataBind dataBind)
throws SQLException {
StringBuilder bindLog = new StringBuilder();
bind(bindParams, dataBind, bindLog);
return bindLog.toString();
}
/**
* Bind the list of positionedParameters in BindParams.
*/
public void bind(BindParams bindParams, DataBind dataBind, StringBuilder bindLog)
throws SQLException {
bind(bindParams.positionedParameters(), dataBind, bindLog);
}
/**
* Bind the list of parameters..
*/
public void bind(List list, DataBind dataBind, StringBuilder bindLog)
throws SQLException {
CallableStatement cstmt = null;
if (dataBind.getPstmt() instanceof CallableStatement) {
cstmt = (CallableStatement) dataBind.getPstmt();
}
// the iterator is assumed to be in the correct order
Object value = null;
try {
for (int i = 0; i < list.size(); i++) {
BindParams.Param param = list.get(i);
if (param.isOutParam() && cstmt != null){
cstmt.registerOutParameter(dataBind.nextPos(), param.getType());
if (param.isInParam()) {
dataBind.decrementPos();
}
}
if (param.isInParam()) {
value = param.getInValue();
if (bindLog != null) {
if (param.isEncryptionKey()){
bindLog.append("****");
} else {
bindLog.append(value);
}
bindLog.append(", ");
}
if (value == null) {
// this doesn't work for query predicates
bindObject(dataBind, null, param.getType());
} else {
bindObject(dataBind, value);
}
}
}
} catch (SQLException ex) {
logger.warning(Message.msg("fetch.bind.error", "" + (dataBind.currentPos() - 1), value));
throw ex;
}
}
/**
* Bind an Object with unknown data type.
*/
public void bindObject(DataBind dataBind, Object value) throws SQLException {
if (value == null) {
// null of unknown type
bindObject(dataBind, null, Types.OTHER);
} else {
ScalarType> type = typeManager.getScalarType(value.getClass());
if (type == null){
// the type is not registered with the TypeManager.
String msg = "No ScalarType registered for "+value.getClass();
throw new PersistenceException(msg);
} else if (!type.isJdbcNative()) {
// convert to a JDBC native type
value = type.toJdbcType(value);
}
int dbType = type.getJdbcType();
bindObject(dataBind, value, dbType);
}
}
/**
* bind a single value.
*
* Note that java.math.BigInteger is supported by converting it to a Long.
*
*
* Note if we get a java.util.Date or java.util.Calendar then these have
* been anonymously passed in (UpdateSql etc). There is a global setting to
* convert then to a java.sql.Date or java.sql.Timestamp for binding. The
* default is that both are converted to java.sql.Timestamp.
*
*/
public void bindObject(DataBind dataBind, Object data, int dbType)
throws SQLException {
if (data == null){
dataBind.setNull(dbType);
return;
}
switch (dbType) {
case java.sql.Types.LONGVARCHAR:
bindLongVarChar(dataBind, data);
break;
case java.sql.Types.LONGVARBINARY:
bindLongVarBinary(dataBind, data);
break;
case java.sql.Types.CLOB:
bindClob(dataBind, data);
break;
case java.sql.Types.BLOB:
bindBlob(dataBind, data);
break;
default:
bindSimpleData(dataBind, dbType, data);
}
}
/**
* Binds the value to the statement according to the data type.
*/
private void bindSimpleData(DataBind b, int dataType, Object data)
throws SQLException {
try {
switch (dataType) {
case java.sql.Types.BOOLEAN:
Boolean bo = (Boolean) data;
b.setBoolean(bo.booleanValue());
break;
case java.sql.Types.BIT:
// Types.BIT should map to Java Boolean
Boolean bitBool = (Boolean) data;
b.setBoolean(bitBool.booleanValue());
break;
case java.sql.Types.VARCHAR:
b.setString((String) data);
break;
case java.sql.Types.CHAR:
b.setString(data.toString());
break;
case java.sql.Types.TINYINT:
b.setByte(((Byte) data).byteValue());
break;
case java.sql.Types.SMALLINT:
b.setShort(((Short) data).shortValue());
break;
case java.sql.Types.INTEGER:
b.setInt(((Integer) data).intValue());
break;
case java.sql.Types.BIGINT:
b.setLong(((Long) data).longValue());
break;
case java.sql.Types.REAL:
b.setFloat(((Float) data).floatValue());
break;
case java.sql.Types.FLOAT:
// DB Float in theory maps to Java Double type
b.setDouble(((Double) data).doubleValue());
break;
case java.sql.Types.DOUBLE:
b.setDouble(((Double) data).doubleValue());
break;
case java.sql.Types.NUMERIC:
b.setBigDecimal((BigDecimal) data);
break;
case java.sql.Types.DECIMAL:
b.setBigDecimal((BigDecimal) data);
break;
case java.sql.Types.TIME:
//pstmt.setTime(index, (java.sql.Time) data, calendar);
b.setTime((java.sql.Time) data);
break;
case java.sql.Types.DATE:
//pstmt.setDate(index, (java.sql.Date) data, calendar);
b.setDate((java.sql.Date) data);
break;
case java.sql.Types.TIMESTAMP:
//pstmt.setTimestamp(index, (java.sql.Timestamp) data, calendar);
b.setTimestamp((java.sql.Timestamp) data);
break;
case java.sql.Types.BINARY:
b.setBytes((byte[]) data);
break;
case java.sql.Types.VARBINARY:
b.setBytes((byte[]) data);
break;
case java.sql.Types.OTHER:
b.setObject(data);
break;
case java.sql.Types.JAVA_OBJECT:
// Not too sure about this.
b.setObject(data);
break;
default:
String msg = Message.msg("persist.bind.datatype", "" + dataType, "" + b.currentPos());
throw new SQLException(msg);
}
} catch (Exception e) {
String dataClass = "Data is null?";
if (data != null) {
dataClass = data.getClass().getName();
}
String m = "Error with property[" + b.currentPos() + "] dt[" + dataType + "]";
m += "data[" + data + "][" + dataClass + "]";
throw new PersistenceException(m, e);
}
}
/**
* Bind String data to a LONGVARCHAR column.
*/
private void bindLongVarChar(DataBind b, Object data)
throws SQLException {
String sd = (String) data;
b.setClob(sd);
}
/**
* Bind byte[] data to a LONGVARBINARY column.
*/
private void bindLongVarBinary(DataBind b, Object data)
throws SQLException {
byte[] bytes = (byte[]) data;
b.setBlob(bytes);
}
/**
* Bind String data to a CLOB column.
*/
private void bindClob(DataBind b, Object data) throws SQLException {
String sd = (String) data;
b.setClob(sd);
}
/**
* Bind byte[] data to a BLOB column.
*/
private void bindBlob(DataBind b, Object data) throws SQLException {
byte[] bytes = (byte[]) data;
b.setBlob(bytes);
}
private boolean isLob(int dbType) {
switch (dbType) {
case Types.CLOB:
return true;
case Types.LONGVARCHAR:
return true;
case Types.BLOB:
return true;
case Types.LONGVARBINARY:
return true;
default:
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy