[#1005] The INSERT INTO .. VALUES .. syntax may cause type-safety issues in some databases. VALUES should be converted before binding
This commit is contained in:
parent
08c6cf0d43
commit
12565c2508
@ -4038,11 +4038,13 @@ public abstract class jOOQAbstractTest<
|
||||
public void testInsertUpdateDelete() throws Exception {
|
||||
reset = false;
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
InsertQuery<A> i = create().insertQuery(TAuthor());
|
||||
i.addValue(TAuthor_ID(), 100);
|
||||
i.addValue(TAuthor_FIRST_NAME(), "Hermann");
|
||||
i.addValue(TAuthor_LAST_NAME(), "Hesse");
|
||||
i.addValue(TAuthor_DATE_OF_BIRTH(), new Date(System.currentTimeMillis()));
|
||||
i.addValue(TAuthor_DATE_OF_BIRTH(), new Date(time));
|
||||
i.addValue(TAuthor_YEAR_OF_BIRTH(), 2010);
|
||||
|
||||
// Check insertion of UDTs and Enums if applicable
|
||||
@ -4056,6 +4058,9 @@ public abstract class jOOQAbstractTest<
|
||||
assertEquals("Hermann", author.getValue(TAuthor_FIRST_NAME()));
|
||||
assertEquals("Hesse", author.getValue(TAuthor_LAST_NAME()));
|
||||
|
||||
// TODO [#1009] This doesn't work yet. Add more substantial tz tests
|
||||
// assertEquals(time, author.getValue(TAuthor_DATE_OF_BIRTH()).getTime());
|
||||
|
||||
Map<Field<?>, String> map = new HashMap<Field<?>, String>();
|
||||
map.put(TAuthor_FIRST_NAME(), "Hermie");
|
||||
|
||||
@ -4210,9 +4215,11 @@ public abstract class jOOQAbstractTest<
|
||||
|
||||
A author1 = create().selectFrom(TAuthor()).where(TAuthor_ID().equal(5)).fetchOne();
|
||||
assertNotNull(author1);
|
||||
assertEquals(37, (int) author1.getValue(TAuthor_ID()));
|
||||
assertEquals(5, (int) author1.getValue(TAuthor_ID()));
|
||||
assertEquals("Smith", author1.getValue(TAuthor_LAST_NAME()));
|
||||
assertEquals(new Date(0), author1.getValue(TAuthor_DATE_OF_BIRTH()));
|
||||
|
||||
// TODO [#1009] This doesn't work yet. Add more substantial tz tests
|
||||
// assertEquals(0L, author1.getValue(TAuthor_DATE_OF_BIRTH()).getTime());
|
||||
assertEquals(1980, (int) author1.getValue(TAuthor_YEAR_OF_BIRTH()));
|
||||
|
||||
// Implicit field list
|
||||
|
||||
@ -54,6 +54,7 @@ import org.jooq.Query;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.tools.Convert;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -109,7 +110,7 @@ class InsertImpl<R extends Record>
|
||||
|
||||
@Override
|
||||
public final InsertImpl<R> values(Object... values) {
|
||||
return values0(vals(values));
|
||||
return values0(vals(convert(values)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -119,11 +120,52 @@ class InsertImpl<R extends Record>
|
||||
|
||||
@Override
|
||||
public final InsertImpl<R> values(Collection<?> values) {
|
||||
return values0(vals(values.toArray()));
|
||||
return values0(vals(convert(values.toArray())));
|
||||
}
|
||||
|
||||
/**
|
||||
* [#1005] Convert values from the <code>VALUES</code> clause to appropriate
|
||||
* values as specified by the <code>INTO</code> clause's column list.
|
||||
*/
|
||||
final Object[] convert(Object[] values) {
|
||||
if (values != null) {
|
||||
Object[] result = new Object[values.length];
|
||||
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
|
||||
// TODO [#1008] Should fields be cast? Check this with
|
||||
// appropriate integration tests
|
||||
if (values[i] instanceof Field<?>) {
|
||||
result[i] = values[i];
|
||||
}
|
||||
else {
|
||||
result[i] = Convert.convert(values[i], getFields().get(i).getType());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final InsertImpl<R> values0(List<Field<?>> values) {
|
||||
if (getFields().size() != values.size()) {
|
||||
throw new IllegalArgumentException("The number of values must match the number of fields");
|
||||
}
|
||||
|
||||
getDelegate().newRecord();
|
||||
for (int i = 0; i < getFields().size(); i++) {
|
||||
// javac has trouble when inferring Object for T. Use Void instead
|
||||
getDelegate().addValue((Field<Void>) getFields().get(i), (Field<Void>) values.get(i));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private final List<Field<?>> getFields() {
|
||||
|
||||
// [#885] If this insert is called with an implicit field name set, take
|
||||
// the fields from the underlying table.
|
||||
@ -131,17 +173,7 @@ class InsertImpl<R extends Record>
|
||||
fields.addAll(into.getFields());
|
||||
}
|
||||
|
||||
if (fields.size() != values.size()) {
|
||||
throw new IllegalArgumentException("The number of values must match the number of fields");
|
||||
}
|
||||
|
||||
getDelegate().newRecord();
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
// javac has trouble when inferring Object for T. Use Void instead
|
||||
getDelegate().addValue((Field<Void>) fields.get(i), (Field<Void>) values.get(i));
|
||||
}
|
||||
|
||||
return this;
|
||||
return fields;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -321,12 +321,12 @@ public final class Convert {
|
||||
|
||||
// Date types can be converted among each other
|
||||
else if (java.util.Date.class.isAssignableFrom(fromClass)) {
|
||||
return (T) toDate(((java.util.Date) from).getTime(), toClass);
|
||||
return toDate(((java.util.Date) from).getTime(), toClass);
|
||||
}
|
||||
|
||||
// Long may also be converted into a date type
|
||||
else if ((fromClass == Long.class || fromClass == long.class) && java.util.Date.class.isAssignableFrom(toClass)) {
|
||||
return (T) toDate((Long) from, toClass);
|
||||
return toDate((Long) from, toClass);
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,23 +336,24 @@ public final class Convert {
|
||||
/**
|
||||
* Convert a long timestamp to any date type
|
||||
*/
|
||||
private static Object toDate(long time, Class<?> toClass) {
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T toDate(long time, Class<T> toClass) {
|
||||
if (toClass == Date.class) {
|
||||
return new Date(time);
|
||||
return (T) new Date(time);
|
||||
}
|
||||
else if (toClass == Time.class) {
|
||||
return new Time(time);
|
||||
return (T) new Time(time);
|
||||
}
|
||||
else if (toClass == Timestamp.class) {
|
||||
return new Timestamp(time);
|
||||
return (T) new Timestamp(time);
|
||||
}
|
||||
else if (toClass == java.util.Date.class) {
|
||||
return new java.util.Date(time);
|
||||
return (T) new java.util.Date(time);
|
||||
}
|
||||
else if (toClass == Calendar.class) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTimeInMillis(time);
|
||||
return calendar;
|
||||
return (T) calendar;
|
||||
}
|
||||
|
||||
throw fail(time, toClass);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user