Skip to content

Commit

Permalink
[SQLLINE-440] Support legacy date/time format
Browse files Browse the repository at this point in the history
Co-authored-by: Richard Antal <antal97richard@gmail.com>
  • Loading branch information
stoty and richardantal committed Feb 24, 2023
1 parent f7889ec commit 4fdeebf
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 24 deletions.
80 changes: 61 additions & 19 deletions src/main/java/sqlline/Rows.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ abstract class Rows implements Iterator<Rows.Row> {
final DateFormat timeFormat;
final DateFormat timestampFormat;
final String nullValue;
final boolean useToStringForDate;
final boolean useToStringForTime;
final boolean useToStringForTimestamp;
final boolean useToStringForNumber;
final boolean escapeOutput;

Rows(SqlLine sqlLine, ResultSet rs) throws SQLException {
Expand All @@ -56,29 +60,61 @@ abstract class Rows implements Iterator<Rows.Row> {
primaryKeys = new Boolean[count];
if (sqlLine.getOpts().isDefault(BuiltInProperty.NUMBER_FORMAT)) {
numberFormat = null;
useToStringForNumber = false;
} else {
final String pattern =
sqlLine.getOpts().get(BuiltInProperty.NUMBER_FORMAT);
numberFormat = new DecimalFormat(pattern,
DecimalFormatSymbols.getInstance(Locale.ROOT));
if ("".equals(pattern)) {
numberFormat = null;
useToStringForNumber = true;
} else {
numberFormat =
new DecimalFormat(pattern,
DecimalFormatSymbols.getInstance(Locale.ROOT));
useToStringForNumber = false;
}
}
if (sqlLine.getOpts().isDefault(BuiltInProperty.DATE_FORMAT)) {
dateFormat = null;
useToStringForDate = false;
} else {
String pattern = sqlLine.getOpts().get(BuiltInProperty.DATE_FORMAT);
dateFormat = new SimpleDateFormat(pattern, Locale.ROOT);
String pattern =
sqlLine.getOpts().get(BuiltInProperty.DATE_FORMAT);
if ("".equals(pattern)) {
dateFormat = null;
useToStringForDate = true;
} else {
dateFormat = new SimpleDateFormat(pattern, Locale.ROOT);
useToStringForDate = false;
}
}
if (sqlLine.getOpts().isDefault(BuiltInProperty.TIME_FORMAT)) {
timeFormat = null;
useToStringForTime = false;
} else {
String pattern = sqlLine.getOpts().get(BuiltInProperty.TIME_FORMAT);
timeFormat = new SimpleDateFormat(pattern, Locale.ROOT);
String pattern =
sqlLine.getOpts().get(BuiltInProperty.TIME_FORMAT);
if ("".equals(pattern)) {
timeFormat = null;
useToStringForTime = true;
} else {
timeFormat = new SimpleDateFormat(pattern, Locale.ROOT);
useToStringForTime = false;
}
}
if (sqlLine.getOpts().isDefault(BuiltInProperty.TIMESTAMP_FORMAT)) {
timestampFormat = null;
useToStringForTimestamp = false;
} else {
String pattern = sqlLine.getOpts().get(BuiltInProperty.TIMESTAMP_FORMAT);
timestampFormat = new SimpleDateFormat(pattern, Locale.ROOT);
String pattern =
sqlLine.getOpts().get(BuiltInProperty.TIMESTAMP_FORMAT);
if ("".equals(pattern)) {
timestampFormat = null;
useToStringForTimestamp = true;
} else {
timestampFormat = new SimpleDateFormat(pattern, Locale.ROOT);
useToStringForTimestamp = false;
}
}
if (sqlLine.getOpts().isDefault(BuiltInProperty.NULL_VALUE)) {
nullValue = null;
Expand Down Expand Up @@ -268,7 +304,7 @@ class Row {
case Types.DOUBLE:
case Types.DECIMAL:
case Types.NUMERIC:
setFormat(rs.getObject(i + 1), numberFormat, i);
setFormat(rs, numberFormat, useToStringForNumber, i);
break;
case Types.BIT:
case Types.CLOB:
Expand All @@ -279,16 +315,16 @@ class Row {
case Types.ROWID:
case Types.NCLOB:
case Types.SQLXML:
setFormat(rs.getObject(i + 1), null, i);
setFormat(rs, null, false, i);
break;
case Types.TIME:
setFormat(rs.getObject(i + 1), timeFormat, i);
setFormat(rs, timeFormat, useToStringForTime, i);
break;
case Types.DATE:
setFormat(rs.getObject(i + 1), dateFormat, i);
setFormat(rs, dateFormat, useToStringForDate, i);
break;
case Types.TIMESTAMP:
setFormat(rs.getObject(i + 1), timestampFormat, i);
setFormat(rs, timestampFormat, useToStringForTimestamp, i);
break;
default:
values[i] = rs.getString(i + 1);
Expand All @@ -304,13 +340,19 @@ class Row {
}
}

private void setFormat(Object o, Format format, int i) {
if (o == null) {
values[i] = String.valueOf(nullValue);
} else if (format != null) {
values[i] = format.format(o);
private void setFormat(ResultSet rs, Format format, boolean useToString,
int i) throws SQLException {
if (useToString) {
values[i] = rs.getString(i + 1);
} else {
values[i] = o.toString();
Object o = rs.getObject(i + 1);
if (o == null) {
values[i] = String.valueOf(nullValue);
} else if (format != null) {
values[i] = format.format(o);
} else {
values[i] = o.toString();
}
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/sqlline/SqlLineOpts.java
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,10 @@ public void setNumberFormat(String numberFormat) {
propertiesMap.put(NUMBER_FORMAT, NUMBER_FORMAT.defaultValue());
return;
}
if ("".equals(numberFormat)) {
propertiesMap.put(NUMBER_FORMAT, numberFormat);
return;
}
try {
NumberFormat nf = new DecimalFormat(numberFormat,
DecimalFormatSymbols.getInstance(Locale.ROOT));
Expand Down Expand Up @@ -1052,6 +1056,9 @@ private String getValidDateTimePatternOrThrow(String dateTimePattern) {
if (DEFAULT.equalsIgnoreCase(dateTimePattern)) {
return dateTimePattern;
}
if ("".equals(dateTimePattern)) {
return dateTimePattern;
}
try {
SimpleDateFormat sdf = new SimpleDateFormat(dateTimePattern, Locale.ROOT);
sdf.format(TEST_DATE);
Expand Down
8 changes: 4 additions & 4 deletions src/main/resources/sqlline/manual.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2322,7 +2322,7 @@ Sets the quote character in csv outputFormat. Setting to default causes usage of

dateformat

The format for how date values are displayed. Setting to default causes date values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.SimpleDateFormat. For example, the setting "YYYY_MM_dd" yields values like "1970_01_01".
The format for how date values are displayed. Setting to default causes date values to be fetched and rendered via ResultSet.getObject.toString. Setting to empty string causes date values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.SimpleDateFormat. For example, the setting "YYYY_MM_dd" yields values like "1970_01_01".

escapeOutput

Expand Down Expand Up @@ -2390,7 +2390,7 @@ The value which will be used instead of null values. Setting to default causes '

numberformat

The format for how numeric values are displayed. Setting to default causes numeric values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.DecimalFormat. For example, the setting "0.###E0" yields scientific notation with up to three fractional digits, values like "6.022E23".
The format for how numeric values are displayed. Setting to default causes numeric values to be fetched and rendered via ResultSet.getObject.toString. Setting to empty string causes numeric values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.DecimalFormat. For example, the setting "0.###E0" yields scientific notation with up to three fractional digits, values like "6.022E23".

outputformat

Expand Down Expand Up @@ -2456,11 +2456,11 @@ The style of tables used to output data for table output format.

timeformat

The format for how time values are displayed. Setting to default causes time values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.SimpleDateFormat. For example, the setting "HH:mm:ss" yields values like "14:12:11".
The format for how time values are displayed. Setting to default causes time values to be fetched and rendered via ResultSet.getObject.toString. Setting to empty string causes time values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.SimpleDateFormat. For example, the setting "HH:mm:ss" yields values like "14:12:11".

timestampformat

The format for how timestamp values are displayed. Setting to default causes timestamp values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.SimpleDateFormat. For example, the setting "dd/MM/YYYY'T'HH:mm:ss" yields values like "01/01/1970T12:32:12".
The format for how timestamp values are displayed. Setting to default causes timestamp values to be fetched and rendered via ResultSet.getObject.toString. Setting to empty string causes timestamp values to be fetched and rendered via ResultSet.getString. Any other setting results in fetch via ResultSet.getObject and rendering via java.text.SimpleDateFormat. For example, the setting "dd/MM/YYYY'T'HH:mm:ss" yields values like "01/01/1970T12:32:12".

trimscripts

Expand Down
17 changes: 16 additions & 1 deletion src/test/java/sqlline/SqlLineArgsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1473,10 +1473,13 @@ public void testTimeFormat() {
// successful patterns
final String okTimeFormat = "!set timeFormat HH:mm:ss\n";
final String defaultTimeFormat = "!set timeFormat default\n";
final String legacyTimeFormat = "!set timeFormat ''\n";
final String okDateFormat = "!set dateFormat YYYY-MM-dd\n";
final String defaultDateFormat = "!set dateFormat default\n";
final String defaultDateFormat = "!set dateFormat ''\n";
final String legacyDateFormat = "!set dateFormat default\n";
final String okTimestampFormat = "!set timestampFormat default\n";
final String defaultTimestampFormat = "!set timestampFormat default\n";
final String legacyTimestampFormat = "!set timestampFormat ''\n";

// successful cases
sqlLine.getOpts().setPropertiesFile(DEV_NULL);
Expand All @@ -1489,6 +1492,10 @@ public void testTimeFormat() {
not(
anyOf(containsString("Error setting configuration"),
containsString("Exception"))));
checkScriptFile(legacyTimeFormat, false, equalTo(SqlLine.Status.OK),
not(
anyOf(containsString("Error setting configuration"),
containsString("Exception"))));
checkScriptFile(okDateFormat, false, equalTo(SqlLine.Status.OK),
not(
anyOf(containsString("Error setting configuration"),
Expand All @@ -1497,6 +1504,10 @@ public void testTimeFormat() {
not(
anyOf(containsString("Error setting configuration"),
containsString("Exception"))));
checkScriptFile(legacyDateFormat, false, equalTo(SqlLine.Status.OK),
not(
anyOf(containsString("Error setting configuration"),
containsString("Exception"))));
checkScriptFile(okTimestampFormat, false, equalTo(SqlLine.Status.OK),
not(
anyOf(containsString("Error setting configuration"),
Expand All @@ -1505,6 +1516,10 @@ public void testTimeFormat() {
not(
anyOf(containsString("Error setting configuration"),
containsString("Exception"))));
checkScriptFile(legacyTimestampFormat, false, equalTo(SqlLine.Status.OK),
not(
anyOf(containsString("Error setting configuration"),
containsString("Exception"))));

// failed patterns
final String wrongTimeFormat = "!set timeFormat qwerty\n";
Expand Down

0 comments on commit 4fdeebf

Please sign in to comment.