Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String length validation (fixes merge conflicts) #3341

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion ebean-api/src/main/java/io/ebean/DataIntegrityException.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import jakarta.persistence.PersistenceException;

/**
* Thrown when a foreign key constraint is enforced.
* Thrown when a foreign key constraint is enforced or a field is too large.
*/
public class DataIntegrityException extends PersistenceException {
private static final long serialVersionUID = -6740171949170180970L;
Expand All @@ -14,4 +14,11 @@ public class DataIntegrityException extends PersistenceException {
public DataIntegrityException(String message, Throwable cause) {
super(message, cause);
}

/**
* Create with message only.
*/
public DataIntegrityException(String message) {
super(message);
}
}
5 changes: 5 additions & 0 deletions ebean-api/src/main/java/io/ebean/DatabaseBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ default DatabaseBuilder alsoIf(BooleanSupplier predicate, Consumer<DatabaseBuild
}
return this;
}

/**
* Set the name of the Database.
*/
Expand Down Expand Up @@ -3103,5 +3104,9 @@ interface Settings extends DatabaseBuilder {
*/
Function<String, String> getMetricNaming();

/**
* Returns the length check mode.
*/
LengthCheck getLengthCheck();
}
}
16 changes: 16 additions & 0 deletions ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {

private String dumpMetricsOptions;

private LengthCheck lengthCheck = LengthCheck.OFF;
private Function<String, String> metricNaming = MetricNamingMatch.INSTANCE;

/**
Expand Down Expand Up @@ -2195,6 +2196,7 @@ protected void loadSettings(PropertiesWrapper p) {
jdbcFetchSizeFindEach = p.getInt("jdbcFetchSizeFindEach", jdbcFetchSizeFindEach);
jdbcFetchSizeFindList = p.getInt("jdbcFetchSizeFindList", jdbcFetchSizeFindList);
databasePlatformName = p.get("databasePlatformName", databasePlatformName);
lengthCheck = p.getEnum(LengthCheck.class, "lengthCheck", lengthCheck);

uuidVersion = p.getEnum(UuidVersion.class, "uuidVersion", uuidVersion);
uuidStateFile = p.get("uuidStateFile", uuidStateFile);
Expand Down Expand Up @@ -2571,6 +2573,20 @@ public DatabaseConfig setMetricNaming(Function<String, String> metricNaming) {
return this;
}

/**
* Returns the length check mode.
*/
public LengthCheck getLengthCheck() {
return lengthCheck;
}

/**
* Sets the length check mode.
*/
public void setLengthCheck(LengthCheck lengthCheck) {
rbygrave marked this conversation as resolved.
Show resolved Hide resolved
this.lengthCheck = lengthCheck;
}

public enum UuidVersion {
VERSION4,
VERSION1,
Expand Down
22 changes: 22 additions & 0 deletions ebean-api/src/main/java/io/ebean/config/LengthCheck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.ebean.config;

/**
* Defines the length-check mode.
*
* @author Roland Praml, FOCONIS AG
*/
public enum LengthCheck {
/**
* By default, length checking is off. This means, strings/jsons and files are passed to the DB and the DB might or might not check the length.
* The DB has to check the data length. Note this is not possible for certain datatypes (e.g. clob without size)
*/
OFF,
/**
* When enabling length check, ebean validates strings/json strings and files before saving them to DB.
*/
ON,
/**
* Same as "ON", but take the UTF8-bytelength for validation. This may be useful, if you have an UTF8 based charset (default for DB2)
*/
UTF8
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,9 @@ public interface DataBinder {
*/
String popJson();

/**
* Returns the last bound object (e.g. for BindValidation). Note for InputStreams you'll get an InputStreamInfo.
*/
Object popLastObject();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.ebean.core.type;

import java.io.InputStream;

/**
* Helper to transports length info of DataBind.setBinaryStream(stream, length) to BindValidation
*
* @author Roland Praml, FOCONIS AG
*/
public final class InputStreamInfo {

private final InputStream stream;
private final long length;

public InputStreamInfo(InputStream stream, long length) {
this.stream = stream;
this.length = length;
}

public InputStream stream() {
return stream;
}

public long length() {
return length;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package io.ebeaninternal.server.bind;

import io.ebean.core.type.DataBinder;
import io.ebean.core.type.InputStreamInfo;
import io.ebeaninternal.api.CoreLog;
import io.ebeaninternal.server.core.timezone.DataTimeZone;

import java.io.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.*;
import java.util.ArrayList;
Expand All @@ -23,6 +27,8 @@ public class DataBind implements DataBinder {
protected int pos;
private String json;

private Object lastObject = null;

public DataBind(DataTimeZone dataTimeZone, PreparedStatement pstmt, Connection connection) {
this.dataTimeZone = dataTimeZone;
this.pstmt = pstmt;
Expand Down Expand Up @@ -65,16 +71,19 @@ public final int currentPos() {
@Override
public void setObject(Object value) throws SQLException {
pstmt.setObject(++pos, value);
lastObject = value;
}

@Override
public final void setObject(Object value, int sqlType) throws SQLException {
pstmt.setObject(++pos, value, sqlType);
lastObject = value;
}

@Override
public void setNull(int jdbcType) throws SQLException {
pstmt.setNull(++pos, jdbcType);
lastObject = null;
}

@Override
Expand All @@ -96,7 +105,7 @@ public final int executeUpdate() throws SQLException {
}
}

private void closeInputStreams() {
public void closeInputStreams() {
if (inputStreams != null) {
for (InputStream inputStream : inputStreams) {
try {
Expand All @@ -117,36 +126,43 @@ public final PreparedStatement getPstmt() {
@Override
public void setString(String value) throws SQLException {
pstmt.setString(++pos, value);
lastObject = value;
}

@Override
public final void setInt(int value) throws SQLException {
pstmt.setInt(++pos, value);
lastObject = null;
}

@Override
public final void setLong(long value) throws SQLException {
pstmt.setLong(++pos, value);
lastObject = null;
}

@Override
public final void setShort(short value) throws SQLException {
pstmt.setShort(++pos, value);
lastObject = null;
}

@Override
public final void setFloat(float value) throws SQLException {
pstmt.setFloat(++pos, value);
lastObject = null;
}

@Override
public final void setDouble(double value) throws SQLException {
pstmt.setDouble(++pos, value);
lastObject = null;
}

@Override
public final void setBigDecimal(BigDecimal value) throws SQLException {
pstmt.setBigDecimal(++pos, value);
lastObject = null;
}

@Override
Expand All @@ -157,6 +173,7 @@ public final void setDate(java.sql.Date value) throws SQLException {
} else {
pstmt.setDate(++pos, value);
}
lastObject = null;
}

@Override
Expand All @@ -167,6 +184,7 @@ public final void setTimestamp(Timestamp value) throws SQLException {
} else {
pstmt.setTimestamp(++pos, value);
}
lastObject = null;
}

@Override
Expand All @@ -177,26 +195,31 @@ public final void setTime(Time value) throws SQLException {
} else {
pstmt.setTime(++pos, value);
}
lastObject = null;
}

@Override
public void setBoolean(boolean value) throws SQLException {
pstmt.setBoolean(++pos, value);
lastObject = null;
}

@Override
public void setBytes(byte[] value) throws SQLException {
pstmt.setBytes(++pos, value);
lastObject = value;
}

@Override
public void setByte(byte value) throws SQLException {
pstmt.setByte(++pos, value);
lastObject = null;
}

@Override
public void setChar(char value) throws SQLException {
pstmt.setString(++pos, String.valueOf(value));
lastObject = null;
}

@Override
Expand All @@ -211,21 +234,31 @@ public void setBinaryStream(InputStream inputStream, long length) throws SQLExce
}
inputStreams.add(inputStream);
pstmt.setBinaryStream(++pos, inputStream, length);
lastObject = new InputStreamInfo(inputStream, length);
}

@Override
public void setBlob(byte[] bytes) throws SQLException {
pstmt.setBinaryStream(++pos, new ByteArrayInputStream(bytes), bytes.length);
lastObject = bytes;
}

@Override
public void setClob(String content) throws SQLException {
pstmt.setCharacterStream(++pos, new StringReader(content), content.length());
lastObject = content;
}

@Override
public void setArray(String arrayType, Object[] elements) throws SQLException {
pstmt.setArray(++pos, connection.createArrayOf(arrayType, elements));
lastObject = null;
}

@Override
public Object popLastObject() {
Object ret = lastObject;
lastObject = null;
return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public final class BeanDescriptorManager implements BeanDescriptorMap, SpiBeanTy
private final String asOfViewSuffix;
private final boolean jacksonCorePresent;
private final int queryPlanTTLSeconds;
private final BindMaxLength bindMaxLength;
private int entityBeanCount;
private List<BeanDescriptor<?>> immutableDescriptorList;
/**
Expand Down Expand Up @@ -160,6 +161,19 @@ public BeanDescriptorManager(InternalConfiguration config) {
this.changeLogListener = config.changeLogListener(bootupClasses.getChangeLogListener());
this.changeLogRegister = config.changeLogRegister(bootupClasses.getChangeLogRegister());
this.jacksonCorePresent = config.isJacksonCorePresent();
this.bindMaxLength = initMaxLength();
}

BindMaxLength initMaxLength() {
LengthCheck lengthCheck = this.config.getLengthCheck();
switch (lengthCheck) {
case OFF:
return null;
case UTF8:
return BindMaxLength.ofUtf8();
default:
return BindMaxLength.ofStandard();
}
}

@Override
Expand Down Expand Up @@ -1501,6 +1515,10 @@ public List<MetaQueryPlan> queryPlanInit(QueryPlanInit request) {
return list;
}

public BindMaxLength bindMaxLength() {
return bindMaxLength;
}

/**
* Comparator to sort the BeanDescriptors by name.
*/
Expand Down
Loading
Loading