[#2665] Implement SPI for RenderContext and BindContext listening to

allow for custom SQL transformation

 * Added INSERT clause implementation draft.
This commit is contained in:
Lukas Eder 2013-08-12 11:26:51 +02:00
parent d7814ffdbc
commit 988979c172
5 changed files with 106 additions and 6 deletions

View File

@ -320,15 +320,76 @@ public enum Clause {
SELECT_ORDER_BY,
// -------------------------------------------------------------------------
// Clauses that are used in an INSERT statement
// -------------------------------------------------------------------------
/**
* A complete <code>INSERT</code> statement.
*/
INSERT,
/**
* The <code>INSERT INTO</code> clause within an {@link #INSERT} statement.
* <p>
* This clause surrounds
* <ul>
* <li>the <code>INSERT INTO</code> keywords</li>
* <li>the table that is being inserted</li>
* </ul>
*/
INSERT_INSERT_INTO,
/**
* The <code>VALUES</code> clause within an {@link #INSERT} statement.
* <p>
* This clause surrounds
* <ul>
* <li>the <code>VALUES</code> keyword</li>
* <li>several {@link #FIELD_ROW} clauses</li>
* </ul>
*/
INSERT_VALUES,
/**
* The <code>SELECT</code> clause within an {@link #INSERT} statement.
* <p>
* This clause surrounds a {@link #SELECT} clause.
*/
INSERT_SELECT,
/**
* The <code>ON DUPLICATE KEY UPDATE</code> clause within an {@link #INSERT}
* statement.
* <p>
* This clause surrounds several
* {@link #INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT} clauses.
* <ul>
* <li>the <code>ON DUPLICATE KEY UPDATE</code> keywords</li>
* <li>several {@link #INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT} clauses</li>
* </ul>
*/
INSERT_ON_DUPLICATE_KEY_UPDATE,
/**
* The <code>ON DUPLICATE KEY UPDATE</code> clause within an {@link #INSERT}
* statement.
* <p>
* This clause surrounds two {@link #FIELD} clauses.
*/
INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT,
/**
* The <code>RETURNING</code> clause within an {@link #INSERT} statement.
* <p>
* This clause surrounds
* <ul>
* <li>the <code>RETURNING</code> keyword</li>
* <li>several {@link #FIELD} clauses</li>
* </ul>
*/
INSERT_RETURNING,
// -------------------------------------------------------------------------
// Clauses that are used in an UPDATE statement
// -------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@
package org.jooq.impl;
import static org.jooq.Clause.DUMMY;
import static org.jooq.Clause.INSERT_VALUES;
import static org.jooq.impl.Utils.visitAll;
import java.util.Collection;
@ -65,8 +66,11 @@ class FieldMapForInsert extends AbstractQueryPartMap<Field<?>, Field<?>> {
public final void toSQL(RenderContext context) {
toSQLReferenceKeys(context);
context.formatSeparator()
.keyword("values ");
.start(INSERT_VALUES)
.keyword("values")
.sql(" ");
toSQLReferenceValues(context);
context.end(INSERT_VALUES);
}
final void toSQLReferenceKeys(RenderContext context) {

View File

@ -35,7 +35,7 @@
*/
package org.jooq.impl;
import static org.jooq.Clause.DUMMY;
import static org.jooq.Clause.INSERT_SELECT;
import static org.jooq.impl.Utils.visitAll;
import java.util.ArrayList;
@ -90,11 +90,15 @@ class FieldMapsForInsert extends AbstractQueryPart {
case INGRES:
case ORACLE:
case SQLITE:
context.start(INSERT_SELECT);
toSQLInsertSelect(context);
context.end(INSERT_SELECT);
break;
default:
toSQL92Values(context);
break;
}
}
@ -142,7 +146,7 @@ class FieldMapsForInsert extends AbstractQueryPart {
@Override
public final Clause[] clauses(Context<?> ctx) {
return new Clause[] { DUMMY };
return null;
}
// -------------------------------------------------------------------------

View File

@ -38,7 +38,9 @@ package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.Clause.INSERT;
import static org.jooq.Clause.INSERT_INSERT_INTO;
import static org.jooq.Clause.INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT;
import static org.jooq.Clause.INSERT_RETURNING;
import static org.jooq.SQLDialect.MARIADB;
import static org.jooq.SQLDialect.MYSQL;
@ -326,17 +328,21 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
}
private final void toSQLInsert(RenderContext context) {
context.keyword("insert")
context.start(INSERT_INSERT_INTO)
.keyword("insert")
.sql(" ")
// [#1295] MySQL natively supports the IGNORE keyword
.keyword((onDuplicateKeyIgnore && asList(MARIADB, MYSQL).contains(context.configuration().dialect())) ? "ignore " : "")
.keyword("into")
.sql(" ")
.visit(getInto())
.end(INSERT_INSERT_INTO)
.sql(" ")
.visit(insertMaps);
context.start(INSERT_RETURNING);
toSQLReturning(context);
context.end(INSERT_RETURNING);
}
private final void bindInsert(BindContext context) {

View File

@ -57,6 +57,9 @@ import static org.jooq.Clause.FIELD;
import static org.jooq.Clause.FIELD_REFERENCE;
import static org.jooq.Clause.FIELD_ROW;
import static org.jooq.Clause.FIELD_VALUE;
import static org.jooq.Clause.INSERT;
import static org.jooq.Clause.INSERT_INSERT_INTO;
import static org.jooq.Clause.INSERT_VALUES;
import static org.jooq.Clause.SELECT;
import static org.jooq.Clause.SELECT_CONNECT_BY;
import static org.jooq.Clause.SELECT_FROM;
@ -201,6 +204,28 @@ public class VisitContextTest extends AbstractTest {
}
}
@Test
public void test_INSERT_VALUES_simple() {
ctx.insertInto(TABLE1)
.values(1, "value", null)
.getSQL();
assertEvents(asList(
asList(INSERT),
asList(INSERT, INSERT_INSERT_INTO),
asList(INSERT, INSERT_INSERT_INTO, TABLE),
asList(INSERT, INSERT_INSERT_INTO, TABLE, TABLE_REFERENCE),
asList(INSERT, INSERT_VALUES),
asList(INSERT, INSERT_VALUES, FIELD_ROW),
asList(INSERT, INSERT_VALUES, FIELD_ROW, FIELD),
asList(INSERT, INSERT_VALUES, FIELD_ROW, FIELD, FIELD_VALUE),
asList(INSERT, INSERT_VALUES, FIELD_ROW, FIELD),
asList(INSERT, INSERT_VALUES, FIELD_ROW, FIELD, FIELD_VALUE),
asList(INSERT, INSERT_VALUES, FIELD_ROW, FIELD),
asList(INSERT, INSERT_VALUES, FIELD_ROW, FIELD, FIELD_VALUE)
));
}
@Test
public void test_UPDATE_SET_simple() {
ctx.update(TABLE1)