[#2665] Implement SPI for RenderContext and BindContext listening to
allow for custom SQL transformation * INSERT statement refactoring to correctly implement clause events.
This commit is contained in:
parent
1c4c459076
commit
094be3cdfb
@ -35,8 +35,6 @@
|
||||
*/
|
||||
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;
|
||||
@ -64,13 +62,32 @@ class FieldMapForInsert extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
|
||||
@Override
|
||||
public final void toSQL(RenderContext context) {
|
||||
toSQLReferenceKeys(context);
|
||||
context.formatSeparator()
|
||||
.start(INSERT_VALUES)
|
||||
.keyword("values")
|
||||
.sql(" ");
|
||||
toSQLReferenceValues(context);
|
||||
context.end(INSERT_VALUES);
|
||||
boolean indent = (size() > 1);
|
||||
|
||||
context.sql("(");
|
||||
|
||||
if (indent) {
|
||||
context.formatIndentStart();
|
||||
}
|
||||
|
||||
String separator = "";
|
||||
for (Field<?> field : values()) {
|
||||
context.sql(separator);
|
||||
|
||||
if (indent) {
|
||||
context.formatNewLine();
|
||||
}
|
||||
|
||||
context.visit(field);
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
if (indent) {
|
||||
context.formatIndentEnd()
|
||||
.formatNewLine();
|
||||
}
|
||||
|
||||
context.sql(")");
|
||||
}
|
||||
|
||||
final void toSQLReferenceKeys(RenderContext context) {
|
||||
@ -108,35 +125,6 @@ class FieldMapForInsert extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
context.sql(")");
|
||||
}
|
||||
|
||||
final void toSQLReferenceValues(RenderContext context) {
|
||||
boolean indent = (size() > 1);
|
||||
|
||||
context.sql("(");
|
||||
|
||||
if (indent) {
|
||||
context.formatIndentStart();
|
||||
}
|
||||
|
||||
String separator = "";
|
||||
for (Field<?> field : values()) {
|
||||
context.sql(separator);
|
||||
|
||||
if (indent) {
|
||||
context.formatNewLine();
|
||||
}
|
||||
|
||||
context.visit(field);
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
if (indent) {
|
||||
context.formatIndentEnd()
|
||||
.formatNewLine();
|
||||
}
|
||||
|
||||
context.sql(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
visitAll(context, keySet());
|
||||
@ -145,7 +133,7 @@ class FieldMapForInsert extends AbstractQueryPartMap<Field<?>, Field<?>> {
|
||||
|
||||
@Override
|
||||
public final Clause[] clauses(Context<?> ctx) {
|
||||
return new Clause[] { DUMMY };
|
||||
return null;
|
||||
}
|
||||
|
||||
final void putFields(Collection<? extends Field<?>> fields) {
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.Clause.INSERT_SELECT;
|
||||
import static org.jooq.Clause.INSERT_VALUES;
|
||||
import static org.jooq.impl.Utils.visitAll;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -56,9 +57,9 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -6227074228534414225L;
|
||||
private static final long serialVersionUID = -6227074228534414225L;
|
||||
|
||||
private final List<FieldMapForInsert> insertMaps;
|
||||
final List<FieldMapForInsert> insertMaps;
|
||||
|
||||
FieldMapsForInsert() {
|
||||
insertMaps = new ArrayList<FieldMapForInsert>();
|
||||
@ -77,7 +78,12 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
|
||||
// Single record inserts can use the standard syntax in any dialect
|
||||
else if (insertMaps.size() == 1 || insertMaps.get(1) == null) {
|
||||
context.visit(insertMaps.get(0));
|
||||
context.formatSeparator()
|
||||
.start(INSERT_VALUES)
|
||||
.keyword("values")
|
||||
.sql(" ")
|
||||
.visit(insertMaps.get(0))
|
||||
.end(INSERT_VALUES);
|
||||
}
|
||||
|
||||
// True SQL92 multi-record inserts aren't always supported
|
||||
@ -97,7 +103,12 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
break;
|
||||
|
||||
default:
|
||||
context.formatSeparator()
|
||||
.start(INSERT_VALUES)
|
||||
.keyword("values")
|
||||
.sql(" ");
|
||||
toSQL92Values(context);
|
||||
context.end(INSERT_VALUES);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -105,8 +116,7 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
}
|
||||
|
||||
private void toSQLInsertSelect(RenderContext context) {
|
||||
insertMaps.get(0).toSQLReferenceKeys(context);
|
||||
context.sql(" ");
|
||||
context.start(INSERT_SELECT);
|
||||
|
||||
Select<Record> select = null;
|
||||
for (FieldMapForInsert map : insertMaps) {
|
||||
@ -123,6 +133,7 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
}
|
||||
|
||||
context.visit(select);
|
||||
context.end(INSERT_SELECT);
|
||||
}
|
||||
|
||||
private void toSQL92Values(RenderContext context) {
|
||||
@ -132,7 +143,7 @@ class FieldMapsForInsert extends AbstractQueryPart {
|
||||
for (FieldMapForInsert map : insertMaps) {
|
||||
if (map != null && i > 0) {
|
||||
context.sql(", ");
|
||||
map.toSQLReferenceValues(context);
|
||||
context.visit(map);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
@ -39,6 +39,7 @@ 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;
|
||||
import static org.jooq.Clause.INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT;
|
||||
import static org.jooq.Clause.INSERT_RETURNING;
|
||||
import static org.jooq.SQLDialect.MARIADB;
|
||||
@ -152,9 +153,11 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
case MYSQL: {
|
||||
toSQLInsert(context);
|
||||
context.formatSeparator()
|
||||
.start(INSERT_ON_DUPLICATE_KEY_UPDATE)
|
||||
.keyword("on duplicate key update")
|
||||
.sql(" ")
|
||||
.visit(updateMap);
|
||||
.visit(updateMap)
|
||||
.end(INSERT_ON_DUPLICATE_KEY_UPDATE);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -336,8 +339,10 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
.keyword("into")
|
||||
.sql(" ")
|
||||
.visit(getInto())
|
||||
.sql(" ");
|
||||
insertMaps.insertMaps.get(0).toSQLReferenceKeys(context);
|
||||
context.sql(" ")
|
||||
.end(INSERT_INSERT_INTO)
|
||||
.sql(" ")
|
||||
.visit(insertMaps);
|
||||
|
||||
context.start(INSERT_RETURNING);
|
||||
|
||||
@ -1145,8 +1145,10 @@ implements
|
||||
// [#999] WHEN NOT MATCHED clause is optional
|
||||
if (notMatchedInsert != null) {
|
||||
context.formatSeparator()
|
||||
.keyword("when not matched then insert").sql(" ")
|
||||
.visit(notMatchedInsert);
|
||||
.keyword("when not matched then insert").sql(" ");
|
||||
notMatchedInsert.toSQLReferenceKeys(context);
|
||||
context.formatSeparator().keyword("values")
|
||||
.sql(" ").visit(notMatchedInsert);
|
||||
}
|
||||
|
||||
// [#998] Oracle MERGE extension: WHEN NOT MATCHED THEN INSERT .. WHERE
|
||||
|
||||
@ -59,6 +59,7 @@ 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_RETURNING;
|
||||
import static org.jooq.Clause.INSERT_VALUES;
|
||||
import static org.jooq.Clause.SELECT;
|
||||
import static org.jooq.Clause.SELECT_CONNECT_BY;
|
||||
@ -215,14 +216,20 @@ public class VisitContextTest extends AbstractTest {
|
||||
asList(INSERT, INSERT_INSERT_INTO),
|
||||
asList(INSERT, INSERT_INSERT_INTO, TABLE),
|
||||
asList(INSERT, INSERT_INSERT_INTO, TABLE, TABLE_REFERENCE),
|
||||
asList(INSERT, INSERT_INSERT_INTO, FIELD),
|
||||
asList(INSERT, INSERT_INSERT_INTO, FIELD, FIELD_REFERENCE),
|
||||
asList(INSERT, INSERT_INSERT_INTO, FIELD),
|
||||
asList(INSERT, INSERT_INSERT_INTO, FIELD, FIELD_REFERENCE),
|
||||
asList(INSERT, INSERT_INSERT_INTO, FIELD),
|
||||
asList(INSERT, INSERT_INSERT_INTO, FIELD, FIELD_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)
|
||||
asList(INSERT, INSERT_VALUES, FIELD),
|
||||
asList(INSERT, INSERT_VALUES, FIELD, FIELD_VALUE),
|
||||
asList(INSERT, INSERT_VALUES, FIELD),
|
||||
asList(INSERT, INSERT_VALUES, FIELD, FIELD_VALUE),
|
||||
asList(INSERT, INSERT_VALUES, FIELD),
|
||||
asList(INSERT, INSERT_VALUES, FIELD, FIELD_VALUE),
|
||||
asList(INSERT, INSERT_RETURNING)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user