[#2199] Allow for INSERT and UPDATE of pre-existing records through SET

[ Record ] clauses
This commit is contained in:
Lukas Eder 2013-02-15 12:17:04 +01:00
parent b89f139bc3
commit ff12bbc730
11 changed files with 135 additions and 42 deletions

View File

@ -312,7 +312,12 @@ class InsertDSL extends Generators {
return this;
}
@Override
public final InsertImpl set(Record record) {
return set(Utils.map(record));
}
@Override
public final InsertImpl newRecord() {
getDelegate().newRecord();

View File

@ -66,34 +66,46 @@ public interface InsertOnDuplicateSetStep<R extends Record> {
/**
* Set values for <code>UPDATE</code> in the <code>INSERT</code> statement's
* <code>ON DUPLICATE KEY UPDATE</code> clause
* <code>ON DUPLICATE KEY UPDATE</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, MYSQL, ORACLE, SQLSERVER, SYBASE })
<T> InsertOnDuplicateSetMoreStep<R> set(Field<T> field, T value);
/**
* Set values for <code>UPDATE</code> in the <code>INSERT</code> statement's
* <code>ON DUPLICATE KEY UPDATE</code> clause
* <code>ON DUPLICATE KEY UPDATE</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, MYSQL, ORACLE, SQLSERVER, SYBASE })
<T> InsertOnDuplicateSetMoreStep<R> set(Field<T> field, Field<T> value);
/**
* Set values for <code>UPDATE</code> in the <code>INSERT</code> statement's
* <code>ON DUPLICATE KEY UPDATE</code> clause
* <code>ON DUPLICATE KEY UPDATE</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, MYSQL, ORACLE, SQLSERVER, SYBASE })
<T> InsertOnDuplicateSetMoreStep<R> set(Field<T> field, Select<? extends Record1<T>> value);
/**
* Set multiple values for <code>UPDATE</code> in the <code>INSERT</code>
* statement's <code>ON DUPLICATE KEY UPDATE</code> clause
* statement's <code>ON DUPLICATE KEY UPDATE</code> clause.
* <p>
* Please assure that key/value pairs have matching <code>&lt;T&gt;</code>
* types. Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>
* Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>. jOOQ will attempt to convert values to their
* corresponding field's type.
*/
@Support({ CUBRID, DB2, HSQLDB, MYSQL, ORACLE, SQLSERVER, SYBASE })
InsertOnDuplicateSetMoreStep<R> set(Map<? extends Field<?>, ?> map);
/**
* Set multiple values for <code>UPDATE</code> in the <code>INSERT</code>
* statement's <code>ON DUPLICATE KEY UPDATE</code> clause.
* <p>
* This is the same as calling {@link #set(Map)} with the argument record
* treated as a <code>Map<Field<?>, Object></code>.
*
* @see #set(Map)
*/
@Support({ CUBRID, DB2, HSQLDB, MYSQL, ORACLE, SQLSERVER, SYBASE })
InsertOnDuplicateSetMoreStep<R> set(Record record);
}

View File

@ -63,54 +63,65 @@ import org.jooq.impl.Executor;
public interface InsertSetStep<R extends Record> {
/**
* Set a value for a field in the <code>INSERT</code> statement
* Set a value for a field in the <code>INSERT</code> statement.
*/
@Support
<T> InsertSetMoreStep<R> set(Field<T> field, T value);
/**
* Set a value for a field in the <code>INSERT</code> statement
* Set a value for a field in the <code>INSERT</code> statement.
*/
@Support
<T> InsertSetMoreStep<R> set(Field<T> field, Field<T> value);
/**
* Set a value for a field in the <code>INSERT</code> statement
* Set a value for a field in the <code>INSERT</code> statement.
*/
@Support
<T> InsertSetMoreStep<R> set(Field<T> field, Select<? extends Record1<T>> value);
/**
* Set a value for a field in the <code>INSERT</code> statement
* Set values in the <code>INSERT</code> statement.
* <p>
* Please assure that key/value pairs have matching <code>&lt;T&gt;</code>
* types. Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>
* Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>. jOOQ will attempt to convert values to their
* corresponding field's type.
*/
@Support
InsertSetMoreStep<R> set(Map<? extends Field<?>, ?> map);
/**
* Add values to the insert statement with implicit field names
* Set values in the <code>INSERT</code> statement.
* <p>
* This is the same as calling {@link #set(Map)} with the argument record
* treated as a <code>Map<Field<?>, Object></code>.
*
* @see #set(Map)
*/
@Support
InsertSetMoreStep<R> set(Record record);
/**
* Add values to the insert statement with implicit field names.
*/
@Support
InsertValuesStepN<R> values(Object... values);
/**
* Add values to the insert statement with implicit field names
* Add values to the insert statement with implicit field names.
*/
@Support
InsertValuesStepN<R> values(Field<?>... values);
/**
* Add values to the insert statement with implicit field names
* Add values to the insert statement with implicit field names.
*/
@Support
InsertValuesStepN<R> values(Collection<?> values);
/**
* Use a <code>SELECT</code> statement as the source of values for the
* <code>INSERT</code> statement
* <code>INSERT</code> statement.
* <p>
* This variant of the <code>INSERT .. SELECT</code> statement does not
* allow for specifying a subset of the fields inserted into. It will insert

View File

@ -67,21 +67,21 @@ public interface MergeMatchedSetStep<R extends Record> {
/**
* Set values for <code>UPDATE</code> in the <code>MERGE</code> statement's
* <code>WHEN MATCHED</code> clause
* <code>WHEN MATCHED</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
<T> MergeMatchedSetMoreStep<R> set(Field<T> field, T value);
/**
* Set values for <code>UPDATE</code> in the <code>MERGE</code> statement's
* <code>WHEN MATCHED</code> clause
* <code>WHEN MATCHED</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
<T> MergeMatchedSetMoreStep<R> set(Field<T> field, Field<T> value);
/**
* Set values for <code>UPDATE</code> in the <code>MERGE</code> statement's
* <code>WHEN MATCHED</code> clause
* <code>WHEN MATCHED</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
<T> MergeMatchedSetMoreStep<R> set(Field<T> field, Select<? extends Record1<T>> value);
@ -90,10 +90,22 @@ public interface MergeMatchedSetStep<R extends Record> {
* Set multiple values for <code>UPDATE</code> in the <code>MERGE</code>
* statement's <code>WHEN MATCHED</code> clause.
* <p>
* Please assure that key/value pairs have matching <code>&lt;T&gt;</code>
* types. Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>
* Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>. jOOQ will attempt to convert values to their
* corresponding field's type.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
MergeMatchedSetMoreStep<R> set(Map<? extends Field<?>, ?> map);
/**
* Set multiple values for <code>UPDATE</code> in the <code>MERGE</code>
* statement's <code>WHEN MATCHED</code> clause.
* <p>
* This is the same as calling {@link #set(Map)} with the argument record
* treated as a <code>Map<Field<?>, Object></code>.
*
* @see #set(Map)
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
MergeMatchedSetMoreStep<R> set(Record record);
}

View File

@ -67,21 +67,21 @@ public interface MergeNotMatchedSetStep<R extends Record> {
/**
* Set values for <code>INSERT</code> in the <code>MERGE</code> statement's
* <code>WHEN NOT MATCHED</code> clause
* <code>WHEN NOT MATCHED</code> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
<T> MergeNotMatchedSetMoreStep<R> set(Field<T> field, T value);
/**
* Set values for <code>INSERT</code> in the <code>MERGE</code> statement's
* <code>WHEN NOT MATCHED</INSERT> clause
* <code>WHEN NOT MATCHED</INSERT> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
<T> MergeNotMatchedSetMoreStep<R> set(Field<T> field, Field<T> value);
/**
* Set values for <code>INSERT</code> in the <code>MERGE</code> statement's
* <code>WHEN NOT MATCHED</INSERT> clause
* <code>WHEN NOT MATCHED</INSERT> clause.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
<T> MergeMatchedSetMoreStep<R> set(Field<T> field, Select<? extends Record1<T>> value);
@ -90,10 +90,22 @@ public interface MergeNotMatchedSetStep<R extends Record> {
* Set multiple values for <code>INSERT</code> in the <code>MERGE</code>
* statement's <code>WHEN NOT MATCHED</code> clause.
* <p>
* Please assure that key/value pairs have matching <code>&lt;T&gt;</code>
* types. Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>
* Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>. jOOQ will attempt to convert values to their
* corresponding field's type.
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
MergeNotMatchedSetMoreStep<R> set(Map<? extends Field<?>, ?> map);
/**
* Set multiple values for <code>INSERT</code> in the <code>MERGE</code>
* statement's <code>WHEN NOT MATCHED</code> clause.
* <p>
* This is the same as calling {@link #set(Map)} with the argument record
* treated as a <code>Map<Field<?>, Object></code>.
*
* @see #set(Map)
*/
@Support({ CUBRID, DB2, HSQLDB, ORACLE, SQLSERVER, SYBASE })
MergeNotMatchedSetMoreStep<R> set(Record record);
}

View File

@ -77,9 +77,9 @@ public interface StoreQuery<R extends Record> extends Query {
/**
* Add multiple values to the store statement.
* <p>
* Please assure that key/value pairs have matching <code>&lt;T&gt;</code>
* types. Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>
* Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>. jOOQ will attempt to convert values to their
* corresponding field's type.
*/
@Support
void addValues(Map<? extends Field<?>, ?> map);

View File

@ -55,30 +55,40 @@ import java.util.Map;
public interface UpdateSetStep<R extends Record> {
/**
* Set a value for a field in the <code>UPDATE</code> statement
* Set a value for a field in the <code>UPDATE</code> statement.
*/
@Support
<T> UpdateSetMoreStep<R> set(Field<T> field, T value);
/**
* Set a value for a field in the <code>UPDATE</code> statement
* Set a value for a field in the <code>UPDATE</code> statement.
*/
@Support
<T> UpdateSetMoreStep<R> set(Field<T> field, Field<T> value);
/**
* Set a value for a field in the <code>UPDATE</code> statement
* Set a value for a field in the <code>UPDATE</code> statement.
*/
@Support
<T> UpdateSetMoreStep<R> set(Field<T> field, Select<? extends Record1<T>> value);
/**
* Set a value for a field in the <code>UPDATE</code> statement
* Set a value for a field in the <code>UPDATE</code> statement.
* <p>
* Please assure that key/value pairs have matching <code>&lt;T&gt;</code>
* types. Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>
* Values can either be of type <code>&lt;T&gt;</code> or
* <code>Field&lt;T&gt;</code>. jOOQ will attempt to convert values to their
* corresponding field's type.
*/
@Support
UpdateSetMoreStep<R> set(Map<? extends Field<?>, ?> map);
}
/**
* Set a value for a field in the <code>UPDATE</code> statement.
* <p>
* This is the same as calling {@link #set(Map)} with the argument record
* treated as a <code>Map<Field<?>, Object></code>.
*
* @see #set(Map)
*/
@Support
UpdateSetMoreStep<R> set(Record record);}

View File

@ -465,6 +465,11 @@ class InsertImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
return this;
}
@Override
public final InsertImpl set(Record record) {
return set(Utils.map(record));
}
@Override
public final InsertImpl newRecord() {
getDelegate().newRecord();

View File

@ -696,6 +696,11 @@ implements
return this;
}
@Override
public final MergeImpl set(Record record) {
return set(Utils.map(record));
}
@Override
public final MergeImpl whenNotMatchedThenInsert() {
return whenNotMatchedThenInsert(Collections.<Field<?>>emptyList());

View File

@ -151,6 +151,11 @@ final class UpdateImpl<R extends Record>
return this;
}
@Override
public final UpdateImpl<R> set(Record record) {
return set(Utils.map(record));
}
// [jooq-tools] START [set]
@Generated("This method was generated using jOOQ-tools")
@Override

View File

@ -71,7 +71,9 @@ import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
@ -567,6 +569,20 @@ final class Utils {
return array == null ? Collections.<T>emptyList() : Arrays.asList(array);
}
/**
* Turn a {@link Record} into a {@link Map}
*/
static final Map<Field<?>, Object> map(Record record) {
Map<Field<?>, Object> result = new LinkedHashMap<Field<?>, Object>();
int size = record.size();
for (int i = 0; i < size; i++) {
result.put(record.field(i), record.getValue(i));
}
return result;
}
/**
* Extract the first item from an iterable or <code>null</code>, if there is
* no such item, or if iterable itself is <code>null</code>