[#813] Add DSL support for INSERT .. RETURNING

This commit is contained in:
Lukas Eder 2011-08-30 22:34:35 +00:00
parent 2585672f88
commit 243ab8700b
6 changed files with 232 additions and 4 deletions

View File

@ -3563,6 +3563,7 @@ public abstract class jOOQAbstractTest<
assertEquals(0, create().fetch(T785()).size());
}
@SuppressWarnings("unchecked")
@Test
public void testInsertReturning() throws Exception {
if (TTriggers() == null) {
@ -3617,6 +3618,26 @@ public abstract class jOOQAbstractTest<
// TODO [#813] DSL querying
// ------------------------
TableRecord<T> returned = (TableRecord<T>)
create().insertInto(TTriggers(), TTriggers_COUNTER())
.values(0)
.returning()
.fetchOne();
assertNotNull(returned);
assertEquals(++ID, (int) returned.getValue(TTriggers_ID()));
assertEquals(2*ID, (int) returned.getValue(TTriggers_COUNTER()));
returned = (TableRecord<T>)
create().insertInto(TTriggers(), TTriggers_COUNTER())
.values(0)
.returning(TTriggers_ID())
.fetchOne();
assertNotNull(returned);
assertEquals(++ID, (int) returned.getValue(TTriggers_ID()));
assertNull(returned.getValue(TTriggers_COUNTER()));
returned.refreshUsing(TTriggers_ID());
assertEquals(2*ID, (int) returned.getValue(TTriggers_COUNTER()));
// store() and similar methods
T triggered = create().newRecord(TTriggers());

View File

@ -54,7 +54,7 @@ import org.jooq.impl.Factory;
*
* @author Lukas Eder
*/
public interface InsertOnDuplicateStep extends InsertFinalStep {
public interface InsertOnDuplicateStep extends InsertFinalStep, InsertReturningStep {
/**
* Add an <code>ON DUPLICATE KEY UPDATE</code> clause to this insert query.

View File

@ -156,9 +156,12 @@ public interface InsertQuery<R extends TableRecord<R>> extends StoreQuery<R>, In
* column values as "generated key". If other fields are requested, a second
* statement is issued. Client code must assure transactional integrity
* between the two statements.</li>
* <li>Sybase and SQLite allow for retrieving IDENTITY values as
* <code>@@identity</code> or <code>last_inserted_rowid()</code> values.
* Those values are fetched in a separate <code>SELECT</code> statement. If
* other fields are requested, a second statement is issued. Client code
* must assure transactional integrity between the two statements.</li>
* <li>Ingres support will be added with #808</li>
* <li>Sybase support will be added with #809</li>
* <li>SQLite support will be added with #810</li>
* </ul>
*/
R getReturned();

View File

@ -0,0 +1,79 @@
/**
* Copyright (c) 2009-2011, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq;
import java.sql.SQLException;
/**
* This type is used for the {@link Insert}'s DSL API.
* <p>
* Example: <code><pre>
* Factory create = new Factory();
*
* TableRecord<?> record =
* create.insertInto(table, field1, field2)
* .values(value1, value2)
* .returning(field1)
* .fetchOne();
* </pre></code>
* <p>
* This implemented differently for every dialect:
* <ul>
* <li>Postgres has native support for <code>INSERT .. RETURNING</code> clauses</li>
* <li>HSQLDB, Oracle, and DB2 JDBC drivers allow for retrieving any table
* column as "generated key" in one statement</li>
* <li>Derby, H2, MySQL, SQL Server only allow for retrieving IDENTITY column
* values as "generated key". If other fields are requested, a second statement
* is issued. Client code must assure transactional integrity between the two
* statements.</li>
* <li>Sybase and SQLite allow for retrieving IDENTITY values as
* <code>@@identity</code> or <code>last_inserted_rowid()</code> values. Those
* values are fetched in a separate <code>SELECT</code> statement. If other
* fields are requested, a second statement is issued. Client code must assure
* transactional integrity between the two statements.</li>
* <li>Ingres support will be added with #808</li>
* </ul>
*
* @author Lukas Eder
*/
public interface InsertResultStep extends Insert {
/**
* The record holding returned values as specified by the
* {@link InsertReturningStep}
*/
TableRecord<?> fetchOne() throws SQLException;
}

View File

@ -0,0 +1,99 @@
/**
* Copyright (c) 2009-2011, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOQ" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package org.jooq;
import java.util.Collection;
/**
* This type is used for the {@link Insert}'s DSL API.
* <p>
* Example: <code><pre>
* Factory create = new Factory();
*
* TableRecord<?> record =
* create.insertInto(table, field1, field2)
* .values(value1, value2)
* .returning(field1)
* .fetchOne();
* </pre></code>
* <p>
* This implemented differently for every dialect:
* <ul>
* <li>Postgres has native support for <code>INSERT .. RETURNING</code> clauses</li>
* <li>HSQLDB, Oracle, and DB2 JDBC drivers allow for retrieving any table
* column as "generated key" in one statement</li>
* <li>Derby, H2, MySQL, SQL Server only allow for retrieving IDENTITY column
* values as "generated key". If other fields are requested, a second statement
* is issued. Client code must assure transactional integrity between the two
* statements.</li>
* <li>Sybase and SQLite allow for retrieving IDENTITY values as
* <code>@@identity</code> or <code>last_inserted_rowid()</code> values. Those
* values are fetched in a separate <code>SELECT</code> statement. If other
* fields are requested, a second statement is issued. Client code must assure
* transactional integrity between the two statements.</li>
* <li>Ingres support will be added with #808</li>
* </ul>
*
* @author Lukas Eder
*/
public interface InsertReturningStep {
/**
* Configure the <code>INSERT</code> statement to return all fields in
* <code>R</code>.
*
* @see InsertResultStep
*/
InsertResultStep returning();
/**
* Configure the <code>INSERT</code> statement to return a list of fields in
* <code>R</code>.
*
* @param fields Fields to be returned
* @see InsertResultStep
*/
InsertResultStep returning(Field<?>... fields);
/**
* Configure the <code>INSERT</code> statement to return a list of fields in
* <code>R</code>.
*
* @param fields Fields to be returned
* @see InsertResultStep
*/
InsertResultStep returning(Collection<? extends Field<?>> fields);
}

View File

@ -49,6 +49,7 @@ import org.jooq.Configuration;
import org.jooq.Field;
import org.jooq.InsertOnDuplicateSetMoreStep;
import org.jooq.InsertQuery;
import org.jooq.InsertResultStep;
import org.jooq.InsertSetMoreStep;
import org.jooq.InsertSetStep;
import org.jooq.InsertValuesStep;
@ -65,7 +66,8 @@ class InsertImpl<R extends TableRecord<R>> extends AbstractQueryPart implements
// Cascading interface implementations for Insert behaviour
InsertValuesStep,
InsertSetMoreStep,
InsertOnDuplicateSetMoreStep {
InsertOnDuplicateSetMoreStep,
InsertResultStep {
/**
* Generated UID
@ -185,4 +187,28 @@ class InsertImpl<R extends TableRecord<R>> extends AbstractQueryPart implements
delegate.newRecord();
return this;
}
@Override
public final InsertResultStep returning() {
delegate.setReturning();
return this;
}
@Override
public final InsertResultStep returning(Field<?>... f) {
delegate.setReturning(f);
return this;
}
@Override
public final InsertResultStep returning(Collection<? extends Field<?>> f) {
delegate.setReturning(f);
return this;
}
@Override
public final TableRecord<?> fetchOne() throws SQLException {
delegate.execute();
return delegate.getReturned();
}
}