[jOOQ/jOOQ#8945] [jOOQ/jOOQ#9923] Add support for FOR XML

This includes support for the new org.jooq.XML type
This commit is contained in:
Lukas Eder 2020-03-06 15:16:40 +01:00
parent d70e534bf3
commit 345586e8db
8 changed files with 295 additions and 5 deletions

View File

@ -118,7 +118,7 @@ import static org.jooq.SQLDialect.POSTGRES;
*
* @author Lukas Eder
*/
public interface SelectForUpdateStep<R extends Record> extends SelectOptionStep<R> {
public interface SelectForUpdateStep<R extends Record> extends SelectForStep<R> {
/**
* Add a <code>FOR UPDATE</code> clause to the end of the query.

View File

@ -104,7 +104,7 @@ import static org.jooq.SQLDialect.POSTGRES;
*
* @author Lukas Eder
*/
public interface SelectForUpdateWaitStep<R extends Record> extends SelectOptionStep<R> {
public interface SelectForUpdateWaitStep<R extends Record> extends SelectForStep<R> {
/**
* Add a <code>WAIT</code> clause to the <code>FOR &lt;lock_mode&gt;</code>
@ -115,7 +115,7 @@ public interface SelectForUpdateWaitStep<R extends Record> extends SelectOptionS
* @see SelectQuery#setForLockModeWait(int)
*/
@Support({ MARIADB })
SelectOptionStep<R> wait(int seconds);
SelectForStep<R> wait(int seconds);
/**
* Add a <code>NOWAIT</code> clause to the
@ -124,7 +124,7 @@ public interface SelectForUpdateWaitStep<R extends Record> extends SelectOptionS
* @see SelectQuery#setForLockModeNoWait()
*/
@Support({ MARIADB, MYSQL, POSTGRES })
SelectOptionStep<R> noWait();
SelectForStep<R> noWait();
/**
* Add a <code>WAIT</code> clause to the <code>FOR &lt;lock_mode&gt;</code>
@ -133,5 +133,5 @@ public interface SelectForUpdateWaitStep<R extends Record> extends SelectOptionS
* @see SelectQuery#setForLockModeSkipLocked()
*/
@Support({ MYSQL, POSTGRES })
SelectOptionStep<R> skipLocked();
SelectForStep<R> skipLocked();
}

View File

@ -1197,4 +1197,61 @@ public interface SelectQuery<R extends Record> extends Select<R>, ConditionProvi
}

View File

@ -169,6 +169,7 @@ import org.jooq.Schema;
import org.jooq.Scope;
import org.jooq.TableRecord;
import org.jooq.UDTRecord;
import org.jooq.XML;
import org.jooq.exception.ControlFlowSignal;
import org.jooq.exception.DataTypeException;
import org.jooq.exception.MappingException;
@ -251,6 +252,8 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
return new DefaultJSONBinding(converter, isLob);
else if (type == JSONB.class)
return new DefaultJSONBBinding(converter, isLob);
else if (type == XML.class)
return new DefaultXMLBinding(converter, isLob);
else if (type == LocalDate.class) {
DateToLocalDateConverter c1 = new DateToLocalDateConverter();
@ -4381,6 +4384,51 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
return Types.VARCHAR;
}
}
static final class DefaultXMLBinding<U> extends AbstractBinding<XML, U> {
/**
* Generated UID
*/
private static final long serialVersionUID = 3430629127218407737L;
DefaultXMLBinding(Converter<XML, U> converter, boolean isLob) {
super(converter, isLob);
}
@Override
final void set0(BindingSetStatementContext<U> ctx, XML value) throws SQLException {
ctx.statement().setString(ctx.index(), value.toString());
}
@Override
final void set0(BindingSetSQLOutputContext<U> ctx, XML value) throws SQLException {
ctx.output().writeString(value.toString());
}
@Override
final XML get0(BindingGetResultSetContext<U> ctx) throws SQLException {
String string = ctx.resultSet().getString(ctx.index());
return string == null ? null : XML.valueOf(string);
}
@Override
final XML get0(BindingGetStatementContext<U> ctx) throws SQLException {
String string = ctx.statement().getString(ctx.index());
return string == null ? null : XML.valueOf(string);
}
@Override
final XML get0(BindingGetSQLInputContext<U> ctx) throws SQLException {
String string = ctx.input().readString();
return string == null ? null : XML.valueOf(string);
}
@Override
final int sqltype(Statement statement, Configuration configuration) {
return Types.VARCHAR;
}
}

View File

@ -137,6 +137,7 @@ final class Keywords {
static final Keyword K_DROP_SCHEMA = keyword("drop schema");
static final Keyword K_DROP_TABLE = keyword("drop table");
static final Keyword K_DROP_VIEW = keyword("drop view");
static final Keyword K_ELEMENTS = keyword("elements");
static final Keyword K_ELSE = keyword("else");
static final Keyword K_ELSEIF = keyword("elseif");
static final Keyword K_ELSIF = keyword("elsif");
@ -270,6 +271,7 @@ final class Keywords {
static final Keyword K_OVERLAPS = keyword("overlaps");
static final Keyword K_PARTITION_BY = keyword("partition by");
static final Keyword K_PASSING = keyword("passing");
static final Keyword K_PATH = keyword("path");
static final Keyword K_PERCENT = keyword("percent");
static final Keyword K_PERIOD = keyword("period");
static final Keyword K_PIVOT = keyword("pivot");
@ -307,6 +309,8 @@ final class Keywords {
static final Keyword K_RETURNING = keyword("returning");
static final Keyword K_REVERSE = keyword("reverse");
static final Keyword K_REVOKE = keyword("revoke");
static final Keyword K_RAW = keyword("raw");
static final Keyword K_ROOT = keyword("root");
static final Keyword K_ROW = keyword("row");
static final Keyword K_ROWCOUNT = keyword("rowcount");
static final Keyword K_ROWS = keyword("rows");
@ -384,6 +388,7 @@ final class Keywords {
static final Keyword K_WITH_TIES = keyword("with ties");
static final Keyword K_WITHIN_GROUP = keyword("within group");
static final Keyword K_WITHOUT_ARRAY_WRAPPER = keyword("without_array_wrapper");
static final Keyword K_XML = keyword("xml");
static final Keyword K_XMLTABLE = keyword("xmltable");
static final Keyword K_YEAR = keyword("year");
static final Keyword K_YEAR_MONTH = keyword("year_month");

View File

@ -88,6 +88,7 @@ import org.jooq.Record;
import org.jooq.Result;
import org.jooq.RowId;
import org.jooq.SQLDialect;
import org.jooq.XML;
import org.jooq.types.DayToSecond;
import org.jooq.types.UByte;
import org.jooq.types.UInteger;
@ -676,6 +677,14 @@ public final class SQLDataType {
*/
public static final DataType<JSONB> JSONB = new DefaultDataType<>(null, JSONB.class, "jsonb");
/**
* The {@link XML} type.
* <p>
* This is not a SQL or JDBC standard. This type handles XML types where
* they are supported
*/
public static final DataType<XML> XML = new DefaultDataType<>(null, XML.class, "xml");
// -------------------------------------------------------------------------
// Static initialisation of dialect-specific data types
// -------------------------------------------------------------------------

View File

@ -113,6 +113,9 @@ import org.jooq.SelectConnectByConditionStep;
import org.jooq.SelectFieldOrAsterisk;
import org.jooq.SelectFinalStep;
import org.jooq.SelectForUpdateOfStep;
// ...
// ...
// ...
import org.jooq.SelectHavingConditionStep;
import org.jooq.SelectIntoStep;
import org.jooq.SelectJoinStep;
@ -199,6 +202,12 @@ final class SelectImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
SelectSeekStepN<R>,
SelectSeekLimitStep<R>,
SelectLimitPercentStep<R>,
@ -244,6 +253,13 @@ final class SelectImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
private transient Number offset;
private transient Param<? extends Number> offsetParam;
SelectImpl(Configuration configuration, WithImpl with) {
this(configuration, with, false);
}
@ -1834,6 +1850,93 @@ final class SelectImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
@Override
public final SelectImpl union(Select<? extends R> select) {
return new SelectImpl(getDelegate().union(select));

View File

@ -38,6 +38,7 @@
package org.jooq.impl;
import static java.lang.Boolean.TRUE;
import static java.util.Arrays.asList;
import static org.jooq.Clause.SELECT;
import static org.jooq.Clause.SELECT_CONNECT_BY;
import static org.jooq.Clause.SELECT_EXCEPT;
@ -263,6 +264,8 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
private final TableList from;
private final ConditionProviderImpl condition;
private final ConditionProviderImpl connectBy;
@ -489,6 +492,13 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
// [#1808] TODO: Restrict this field list, in case a restricting fetch()
// method was called to get here
if (fields == null || fields.isEmpty())
fields = getSelect();
// If no projection was specified explicitly, create fields from result
@ -831,6 +841,12 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
// [#1952] SQL Server OPTION() clauses as well as many other optional
// end-of-query clauses are appended to the end of a query
if (!StringUtils.isBlank(option)) {
@ -2187,6 +2203,58 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
@Override
public final List<Field<?>> getSelect() {
return getSelectResolveAllAsterisks(configuration() != null ? configuration().family() : SQLDialect.DEFAULT);