[#1859] Emulate RETURNING with refresh() for some databases

This commit is contained in:
lukaseder 2016-03-10 17:13:59 +01:00
parent a80d955c32
commit a9a52baf81
2 changed files with 34 additions and 16 deletions

View File

@ -41,6 +41,9 @@
package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static java.util.Arrays.asList;
import static org.jooq.SQLDialect.H2;
// ...
import static org.jooq.impl.RecordDelegate.delegate;
import static org.jooq.impl.RecordDelegate.RecordLifecycleType.INSERT;
import static org.jooq.impl.Tools.indexOrFail;
@ -52,7 +55,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.jooq.Configuration;
import org.jooq.DSLContext;
import org.jooq.Field;
import org.jooq.ForeignKey;
@ -170,7 +172,7 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
// [#814] Refresh identity and/or main unique key values
// [#1002] Consider also identity columns of non-updatable records
// [#1537] Avoid refreshing identity columns on batch inserts
Collection<Field<?>> key = setReturningIfNeeded(create.configuration(), insert);
Collection<Field<?>> key = setReturningIfNeeded(insert);
int result = insert.execute();
if (result > 0) {
@ -178,11 +180,17 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
// [#1596] If insert was successful, update timestamp and/or version columns
setRecordVersionAndTimestamp(version, timestamp);
// [#1859] If an insert was successful try fetching the generated values
getReturningIfNeeded(insert, key);
// [#1859] If an insert was successful try fetching the generated
// values. In some databases, this cannot be done via getGeneratedKeys()
if (asList(H2).contains(configuration().family()) && this instanceof UpdatableRecord) {
((UpdatableRecord<?>) this).refresh();
}
else {
getReturningIfNeeded(insert, key);
for (Field<?> storeField : storeFields)
changed(storeField, false);
for (Field<?> storeField : storeFields)
changed(storeField, false);
}
fetched = true;
}
@ -206,18 +214,20 @@ public class TableRecordImpl<R extends TableRecord<R>> extends AbstractRecord im
}
}
final Collection<Field<?>> setReturningIfNeeded(Configuration configuration, StoreQuery<R> query) {
final Collection<Field<?>> setReturningIfNeeded(StoreQuery<R> query) {
Collection<Field<?>> key = null;
if (!TRUE.equals(configuration.data(DATA_OMIT_RETURNING_CLAUSE))) {
if (!TRUE.equals(configuration().data(DATA_OMIT_RETURNING_CLAUSE))) {
// [#1859] Return also non-key columns
if (TRUE.equals(configuration.settings().isReturnAllOnUpdatableRecord()))
if (TRUE.equals(configuration().settings().isReturnAllOnUpdatableRecord()))
key = Arrays.asList(fields());
else
key = getReturning();
query.setReturning(key);
// [#1859] Not all databases support RETURNING clauses on UPDATE
if (query instanceof InsertQuery || !asList().contains(configuration().family()))
query.setReturning(key);
}
return key;

View File

@ -43,6 +43,8 @@ package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static java.util.Arrays.asList;
// ...
import static org.jooq.SQLDialect.H2;
// ...
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.conf.SettingsTools.updatablePrimaryKeys;
import static org.jooq.impl.RecordDelegate.delegate;
@ -238,18 +240,24 @@ public class UpdatableRecordImpl<R extends UpdatableRecord<R>> extends TableReco
}
// [#1596] Check if the record was really changed in the database
// [#1859]
Collection<Field<?>> key = setReturningIfNeeded(configuration(), update);
// [#1859] Specify the returning clause if needed
Collection<Field<?>> key = setReturningIfNeeded(update);
int result = update.execute();
checkIfChanged(result, version, timestamp);
if (result > 0) {
// [#1859] If an update was successful try fetching the generated values
getReturningIfNeeded(update, key);
// [#1859] If an update was successful try fetching the generated
// values. In some databases, this cannot be done via getGeneratedKeys()
if (asList(H2).contains(configuration().family())) {
refresh();
}
else {
getReturningIfNeeded(update, key);
for (Field<?> storeField : storeFields)
changed(storeField, false);
for (Field<?> storeField : storeFields)
changed(storeField, false);
}
}
return result;