[jOOQ/jOOQ#10361] Add JSONFormat.quoteNested() and XMLFormat.quoteNested() flags

This commit is contained in:
Lukas Eder 2020-07-06 10:14:58 +02:00
parent ead4acf617
commit cda0232860
4 changed files with 124 additions and 44 deletions

View File

@ -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 <code>false</code>.
*/
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 <code>\n</code>.
*/
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 <code>2</code>.
*/
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
* <code>true</code>.
*/
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
* <code>true</code>.
*/
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.
*/

View File

@ -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 <code>true</code>.
*/
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 <code>false</code>.
*/
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 <code>\n</code>.
*/
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 <code>2</code>.
*/
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.
*/

View File

@ -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<R extends Record> 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<R extends Record> 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)));

View File

@ -793,7 +793,7 @@ final class LoaderImpl<R extends Record> 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);