diff --git a/jOOQ/src/main/java/org/jooq/JSONFormat.java b/jOOQ/src/main/java/org/jooq/JSONFormat.java
index f4d7bcb4b2..829867bf18 100644
--- a/jOOQ/src/main/java/org/jooq/JSONFormat.java
+++ b/jOOQ/src/main/java/org/jooq/JSONFormat.java
@@ -65,8 +65,8 @@ import static org.jooq.tools.StringUtils.rightPad;
*/
public final class JSONFormat {
- public static final JSONFormat DEFAULT_FOR_RESULTS = new JSONFormat();
- public static final JSONFormat DEFAULT_FOR_RECORDS = new JSONFormat().header(false);
+ public final static JSONFormat DEFAULT_FOR_RESULTS = new JSONFormat();
+ public final static JSONFormat DEFAULT_FOR_RECORDS = new JSONFormat().header(false);
final boolean format;
final String newline;
@@ -74,6 +74,7 @@ public final class JSONFormat {
final String[] indented;
final boolean header;
final RecordFormat recordFormat;
+ final boolean quoteNested;
public JSONFormat() {
this(
@@ -82,7 +83,8 @@ public final class JSONFormat {
2,
null,
true,
- RecordFormat.ARRAY
+ RecordFormat.ARRAY,
+ false
);
}
@@ -92,7 +94,8 @@ public final class JSONFormat {
int indent,
String[] indented,
boolean header,
- RecordFormat recordFormat
+ RecordFormat recordFormat,
+ boolean quoteNested
) {
this.format = format;
this.newline = newline;
@@ -105,75 +108,79 @@ public final class JSONFormat {
};
this.header = header;
this.recordFormat = recordFormat;
+ this.quoteNested = quoteNested;
}
/**
* The new value for the formatting flag, defaulting to false.
*/
- public JSONFormat format(boolean newFormat) {
+ public final JSONFormat format(boolean newFormat) {
return new JSONFormat(
newFormat,
newline,
indent,
null,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The formatting flag.
*/
- public boolean format() {
+ public final boolean format() {
return format;
}
/**
* The new newline character, defaulting to \n.
*/
- public JSONFormat newline(String newNewline) {
+ public final JSONFormat newline(String newNewline) {
return new JSONFormat(
format,
newNewline,
indent,
indented,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The formatting flag.
*/
- public String newline() {
+ public final String newline() {
return format ? newline : "";
}
/**
* The new indentation value, defaulting to 2.
*/
- public JSONFormat indent(int newIndent) {
+ public final JSONFormat indent(int newIndent) {
return new JSONFormat(
format,
newline,
newIndent,
null,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The indentation.
*/
- public int indent() {
+ public final int indent() {
return indent;
}
/**
* Convenience method to get an indentation string at a given level.
*/
- public String indentString(int level) {
+ public final String indentString(int level) {
if (level < indented.length)
return indented[level];
else if (format)
@@ -186,14 +193,15 @@ public final class JSONFormat {
* Whether to emit a header row with column names, defaulting to
* true.
*/
- public JSONFormat header(boolean newHeader) {
+ public final JSONFormat header(boolean newHeader) {
return new JSONFormat(
format,
newline,
indent,
indented,
newHeader,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
@@ -201,7 +209,7 @@ public final class JSONFormat {
* Whether to emit a header row with column names, defaulting to
* true.
*/
- public boolean header() {
+ public final boolean header() {
return header;
}
@@ -209,14 +217,15 @@ public final class JSONFormat {
* The record format to be applied, defaulting to
* {@link RecordFormat#ARRAY}.
*/
- public JSONFormat recordFormat(RecordFormat newRecordFormat) {
+ public final JSONFormat recordFormat(RecordFormat newRecordFormat) {
return new JSONFormat(
format,
newline,
indent,
indented,
header,
- newRecordFormat
+ newRecordFormat,
+ quoteNested
);
}
@@ -224,10 +233,34 @@ public final class JSONFormat {
* The record format to be applied, defaulting to
* {@link RecordFormat#ARRAY}.
*/
- public RecordFormat recordFormat() {
+ public final RecordFormat recordFormat() {
return recordFormat;
}
+ /**
+ * Whether nested {@link JSON} or {@link JSONB} content should be quoted
+ * like a string, or nested into JSON formatted output.
+ */
+ public final JSONFormat quoteNested(boolean newQuoteNested) {
+ return new JSONFormat(
+ format,
+ newline,
+ indent,
+ indented,
+ header,
+ recordFormat,
+ newQuoteNested
+ );
+ }
+
+ /**
+ * Whether nested {@link JSON} or {@link JSONB} content should be quoted
+ * like a string, or nested into JSON formatted output.
+ */
+ public final boolean quoteNested() {
+ return quoteNested;
+ }
+
/**
* The format of individual JSON records.
*/
diff --git a/jOOQ/src/main/java/org/jooq/XMLFormat.java b/jOOQ/src/main/java/org/jooq/XMLFormat.java
index 12a4267217..b9b03937dd 100644
--- a/jOOQ/src/main/java/org/jooq/XMLFormat.java
+++ b/jOOQ/src/main/java/org/jooq/XMLFormat.java
@@ -46,8 +46,8 @@ import static org.jooq.tools.StringUtils.rightPad;
*/
public final class XMLFormat {
- public static final XMLFormat DEFAULT_FOR_RESULTS = new XMLFormat();
- public static final XMLFormat DEFAULT_FOR_RECORDS = new XMLFormat().header(false).xmlns(false);
+ public final static XMLFormat DEFAULT_FOR_RESULTS = new XMLFormat();
+ public final static XMLFormat DEFAULT_FOR_RECORDS = new XMLFormat().header(false).xmlns(false);
final boolean xmlns;
final boolean format;
@@ -56,6 +56,7 @@ public final class XMLFormat {
final String[] indented;
final boolean header;
final RecordFormat recordFormat;
+ final boolean quoteNested;
public XMLFormat() {
this(
@@ -65,7 +66,8 @@ public final class XMLFormat {
2,
null,
true,
- RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE
+ RecordFormat.VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE,
+ false
);
}
@@ -76,7 +78,8 @@ public final class XMLFormat {
int indent,
String[] indented,
boolean header,
- RecordFormat recordFormat
+ RecordFormat recordFormat,
+ boolean quoteNested
) {
this.xmlns = xmlns;
this.format = format;
@@ -90,12 +93,13 @@ public final class XMLFormat {
};
this.header = header;
this.recordFormat = recordFormat;
+ this.quoteNested = quoteNested;
}
/**
* The new value for the xmlns flag, defaulting to true.
*/
- public XMLFormat xmlns(boolean newXmlns) {
+ public final XMLFormat xmlns(boolean newXmlns) {
return new XMLFormat(
newXmlns,
format,
@@ -103,21 +107,22 @@ public final class XMLFormat {
indent,
indented,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The xmlns flag.
*/
- public boolean xmlns() {
+ public final boolean xmlns() {
return xmlns;
}
/**
* The new value for the formatting flag, defaulting to false.
*/
- public XMLFormat format(boolean newFormat) {
+ public final XMLFormat format(boolean newFormat) {
return new XMLFormat(
xmlns,
newFormat,
@@ -125,21 +130,22 @@ public final class XMLFormat {
indent,
null,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The formatting flag.
*/
- public boolean format() {
+ public final boolean format() {
return format;
}
/**
* The new newline character, defaulting to \n.
*/
- public XMLFormat newline(String newNewline) {
+ public final XMLFormat newline(String newNewline) {
return new XMLFormat(
xmlns,
format,
@@ -147,21 +153,22 @@ public final class XMLFormat {
indent,
indented,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The formatting flag.
*/
- public String newline() {
+ public final String newline() {
return format ? newline : "";
}
/**
* The new indentation value, defaulting to 2.
*/
- public XMLFormat indent(int newIndent) {
+ public final XMLFormat indent(int newIndent) {
return new XMLFormat(
xmlns,
format,
@@ -169,21 +176,22 @@ public final class XMLFormat {
newIndent,
null,
header,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The indentation.
*/
- public int indent() {
+ public final int indent() {
return indent;
}
/**
* Convenience method to get an indentation string at a given level.
*/
- public String indentString(int level) {
+ public final String indentString(int level) {
if (level < indented.length)
return indented[level];
else if (format)
@@ -201,7 +209,7 @@ public final class XMLFormat {
* This flag is ignored on {@link Record#formatXML(XMLFormat)} and similar
* methods.
*/
- public XMLFormat header(boolean newHeader) {
+ public final XMLFormat header(boolean newHeader) {
return new XMLFormat(
xmlns,
format,
@@ -209,14 +217,15 @@ public final class XMLFormat {
indent,
indented,
newHeader,
- recordFormat
+ recordFormat,
+ quoteNested
);
}
/**
* The header.
*/
- public boolean header() {
+ public final boolean header() {
return header;
}
@@ -224,7 +233,7 @@ public final class XMLFormat {
* The record format to be applied, defaulting to
* {@link RecordFormat#VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE}.
*/
- public XMLFormat recordFormat(RecordFormat newRecordFormat) {
+ public final XMLFormat recordFormat(RecordFormat newRecordFormat) {
return new XMLFormat(
xmlns,
format,
@@ -232,7 +241,8 @@ public final class XMLFormat {
indent,
indented,
header,
- newRecordFormat
+ newRecordFormat,
+ quoteNested
);
}
@@ -240,10 +250,35 @@ public final class XMLFormat {
* The record format to be applied, defaulting to
* {@link RecordFormat#VALUE_ELEMENTS_WITH_FIELD_ATTRIBUTE}.
*/
- public RecordFormat recordFormat() {
+ public final RecordFormat recordFormat() {
return recordFormat;
}
+ /**
+ * Whether nested {@link XML} content should be quoted like a string, or
+ * nested into XML formatted output.
+ */
+ public final XMLFormat quoteNested(boolean newQuoteNested) {
+ return new XMLFormat(
+ xmlns,
+ format,
+ newline,
+ indent,
+ indented,
+ header,
+ recordFormat,
+ newQuoteNested
+ );
+ }
+
+ /**
+ * Whether nested {@link XML} content should be quoted like a string, or
+ * nested into XML formatted output.
+ */
+ public final boolean quoteNested() {
+ return quoteNested;
+ }
+
/**
* The format of individual XML records.
*/
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractCursor.java b/jOOQ/src/main/java/org/jooq/impl/AbstractCursor.java
index c575179d71..e9387786ba 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractCursor.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractCursor.java
@@ -77,6 +77,8 @@ import org.jooq.DataType;
import org.jooq.EnumType;
import org.jooq.Field;
import org.jooq.Formattable;
+import org.jooq.JSON;
+import org.jooq.JSONB;
import org.jooq.JSONFormat;
import org.jooq.Name;
import org.jooq.Record;
@@ -88,6 +90,7 @@ import org.jooq.TXTFormat;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.TableRecord;
+import org.jooq.XML;
import org.jooq.XMLFormat;
import org.jooq.exception.IOException;
import org.jooq.tools.StringUtils;
@@ -684,6 +687,13 @@ abstract class AbstractCursor extends AbstractFormattable impl
((Formattable) value).formatJSON(writer, format);
}
+ else if (value instanceof JSON && !format.quoteNested()) {
+ writer.write(((JSON) value).data());
+ }
+ else if (value instanceof JSONB && !format.quoteNested()) {
+ writer.write(((JSONB) value).data());
+ }
+
else {
JSONValue.writeJSONString(value, writer);
}
@@ -846,6 +856,8 @@ abstract class AbstractCursor extends AbstractFormattable impl
if (value instanceof Formattable)
((Formattable) value).formatXML(writer, format);
+ else if (value instanceof XML && !format.quoteNested())
+ writer.append(((XML) value).data());
else
writer.append(escapeXML(format0(value, false, false)));
diff --git a/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java b/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java
index 76c58e2df0..7b5d88fb5f 100644
--- a/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java
@@ -793,7 +793,7 @@ final class LoaderImpl implements
// [#5200] When the primary key is not supplied in the data,
// we'll assume it uses an identity, and there will never be duplicates
- // [#10358] The above should be moved inside InsertQueryImpl
+ // [#10358] TODO: The above should be moved inside InsertQueryImpl
// [#7253] Use native onDuplicateKeyIgnore() support
else if (onDuplicate == ON_DUPLICATE_KEY_IGNORE && primaryKey.cardinality() > 0) {
insert.onDuplicateKeyIgnore(true);