commit
d1c81e84b5
@ -0,0 +1,17 @@
|
||||
#example properties file
|
||||
jdbc.Driver=org.h2.Driver
|
||||
jdbc.URL=jdbc:h2:~/test
|
||||
jdbc.Schema=INFORMATION_SCHEMA
|
||||
jdbc.User=sa
|
||||
jdbc.Password=
|
||||
|
||||
generator=org.jooq.util.DefaultGenerator
|
||||
generator.database=org.jooq.util.h2.H2Database
|
||||
generator.database.includes=SCHEMATA,TABLES,COLUMNS,CONSTRAINTS,CROSS_REFERENCES,TYPE_INFO,FUNCTION_ALIASES,FUNCTION_COLUMNS,SEQUENCES
|
||||
generator.database.excludes=
|
||||
generator.generate.deprecated=false
|
||||
generator.generate.instance-fields=false
|
||||
generator.generate.records=false
|
||||
|
||||
generator.target.package=org.jooq.util.h2.information_schema
|
||||
generator.target.directory=./src/main/java
|
||||
@ -0,0 +1,48 @@
|
||||
#example properties file
|
||||
jdbc.Driver=org.h2.Driver
|
||||
#jdbc.URL=jdbc:h2:tcp://localhost/~/test
|
||||
jdbc.URL=jdbc:h2:~/test
|
||||
jdbc.Schema=PUBLIC
|
||||
jdbc.User=sa
|
||||
jdbc.Password=
|
||||
|
||||
generator=org.jooq.util.DefaultGenerator
|
||||
generator.database=org.jooq.util.h2.H2Database
|
||||
generator.database.includes=.*
|
||||
generator.database.excludes=T_BOOK_DETAILS,SYSTEM_SEQUENCE.*
|
||||
|
||||
#Database enum type mappings
|
||||
generator.database.enum-type.BOOLEAN_10=1,0
|
||||
generator.database.enum-type.BOOLEAN_YN_UC="Y",N
|
||||
generator.database.enum-type.BOOLEAN_YN_LC=y,"n"
|
||||
generator.database.enum-type.BOOLEAN_YES_NO_UC="YES","NO"
|
||||
generator.database.enum-type.BOOLEAN_YES_NO_LC=yes,no
|
||||
generator.database.enum-type.BOOLEAN_TRUE_FALSE_UC=TRUE,FALSE
|
||||
generator.database.enum-type.BOOLEAN_TRUE_FALSE_LC=true,false
|
||||
|
||||
generator.database.forced-type.BOOLEAN_10=(?i:(.*?\.)?T_BOOLEANS\.ONE_ZERO)
|
||||
generator.database.forced-type.BOOLEAN_YN_UC=(?i:(.*?\.)?T_BOOLEANS\.Y_N_UC)
|
||||
generator.database.forced-type.BOOLEAN_YN_LC=(?i:(.*?\.)?T_BOOLEANS\.Y_N_LC)
|
||||
generator.database.forced-type.BOOLEAN_YES_NO_UC=(?i:(.*?\.)?T_BOOLEANS\.YES_NO_UC)
|
||||
generator.database.forced-type.BOOLEAN_YES_NO_LC=(?i:(.*?\.)?T_BOOLEANS\.YES_NO_LC)
|
||||
generator.database.forced-type.BOOLEAN_TRUE_FALSE_UC=(?i:(.*?\.)?T_BOOLEANS\.TRUE_FALSE_UC)
|
||||
generator.database.forced-type.BOOLEAN_TRUE_FALSE_LC=(?i:(.*?\.)?T_BOOLEANS\.TRUE_FALSE_LC)
|
||||
|
||||
#[#677] Forced types
|
||||
generator.database.forced-type.BOOLEAN=(?i:(.*?\.)?T_BOOLEANS\.(VC|C|N)_BOOLEAN)
|
||||
|
||||
#Generator configuration
|
||||
generator.generate.relations=true
|
||||
generator.generate.instance-fields=false
|
||||
generator.generate.generated-annotation=false
|
||||
|
||||
#Generate a master data table enum from T_LANGUAGE
|
||||
generator.generate.master-data-tables=T_LANGUAGE,T_658_11,T_658_21,T_658_31,T_658_12,T_658_22,T_658_32
|
||||
generator.generate.master-data-table-literal.T_LANGUAGE=CD
|
||||
generator.generate.master-data-table-description.T_LANGUAGE=DESCRIPTION
|
||||
generator.generate.master-data-table-literal.T_658_12=CD
|
||||
generator.generate.master-data-table-literal.T_658_22=CD
|
||||
generator.generate.master-data-table-literal.T_658_32=CD
|
||||
|
||||
generator.target.package=org.jooq.test.h2.generatedclasses
|
||||
generator.target.directory=./src
|
||||
@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-2.1.0.xsd">
|
||||
<jdbc>
|
||||
<driver>org.h2.Driver</driver>
|
||||
<url>jdbc:h2:~/test</url>
|
||||
<user>sa</user>
|
||||
<password></password>
|
||||
</jdbc>
|
||||
<generator>
|
||||
<name>org.jooq.util.DefaultGenerator</name>
|
||||
<database>
|
||||
<name>org.jooq.util.h2.H2Database</name>
|
||||
<includes>.*</includes>
|
||||
<excludes>T_BOOK_DETAILS,SYSTEM_SEQUENCE.*</excludes>
|
||||
<recordVersionFields>REC_VERSION</recordVersionFields>
|
||||
<recordTimestampFields>REC_TIMESTAMP</recordTimestampFields>
|
||||
<dateAsTimestamp>false</dateAsTimestamp>
|
||||
<unsignedTypes>true</unsignedTypes>
|
||||
<inputSchema>PUBLIC</inputSchema>
|
||||
<masterDataTables>
|
||||
<masterDataTable>
|
||||
<name>T_LANGUAGE</name>
|
||||
<literal>CD</literal>
|
||||
<description>DESCRIPTION</description>
|
||||
</masterDataTable>
|
||||
<masterDataTable>
|
||||
<name>T_658_11</name>
|
||||
</masterDataTable>
|
||||
<masterDataTable>
|
||||
<name>T_658_21</name>
|
||||
</masterDataTable>
|
||||
<masterDataTable>
|
||||
<name>T_658_31</name>
|
||||
</masterDataTable>
|
||||
<masterDataTable>
|
||||
<name>T_658_12</name>
|
||||
<literal>CD</literal>
|
||||
</masterDataTable>
|
||||
<masterDataTable>
|
||||
<name>T_658_22</name>
|
||||
<literal>CD</literal>
|
||||
</masterDataTable>
|
||||
<masterDataTable>
|
||||
<name>T_658_32</name>
|
||||
<literal>CD</literal>
|
||||
</masterDataTable>
|
||||
</masterDataTables>
|
||||
|
||||
<customTypes>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_10</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_10_Converter</converter>
|
||||
</customType>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_TF_LC</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_TF_LC_Converter</converter>
|
||||
</customType>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_TF_UC</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_TF_UC_Converter</converter>
|
||||
</customType>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_YN_LC</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_YN_LC_Converter</converter>
|
||||
</customType>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_YN_UC</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_YN_UC_Converter</converter>
|
||||
</customType>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_YES_NO_LC</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_YES_NO_LC_Converter</converter>
|
||||
</customType>
|
||||
<customType>
|
||||
<name>org.jooq.test._.converters.Boolean_YES_NO_UC</name>
|
||||
<converter>org.jooq.test._.converters.Boolean_YES_NO_UC_Converter</converter>
|
||||
</customType>
|
||||
</customTypes>
|
||||
|
||||
<forcedTypes>
|
||||
<forcedType>
|
||||
<name>BOOLEAN</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.(VC|C|N)_BOOLEAN)</expressions>
|
||||
</forcedType>
|
||||
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_YES_NO_LC</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.YES_NO_LC)</expressions>
|
||||
</forcedType>
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_YES_NO_UC</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.YES_NO_UC)</expressions>
|
||||
</forcedType>
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_YN_LC</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.Y_N_LC)</expressions>
|
||||
</forcedType>
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_YN_UC</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.Y_N_UC)</expressions>
|
||||
</forcedType>
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_TF_LC</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.TRUE_FALSE_LC)</expressions>
|
||||
</forcedType>
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_TF_UC</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.TRUE_FALSE_UC)</expressions>
|
||||
</forcedType>
|
||||
<forcedType>
|
||||
<name>org.jooq.test._.converters.Boolean_10</name>
|
||||
<expressions>(?i:(.*?.)?T_BOOLEANS.ONE_ZERO)</expressions>
|
||||
</forcedType>
|
||||
</forcedTypes>
|
||||
</database>
|
||||
<generate>
|
||||
<relations>true</relations>
|
||||
<navigationMethods>true</navigationMethods>
|
||||
<deprecated>true</deprecated>
|
||||
<instanceFields>false</instanceFields>
|
||||
<generatedAnnotation>false</generatedAnnotation>
|
||||
<records>false</records>
|
||||
<pojos>false</pojos>
|
||||
<interfaces>true</interfaces>
|
||||
<daos>true</daos>
|
||||
<jpaAnnotations>false</jpaAnnotations>
|
||||
</generate>
|
||||
<target>
|
||||
<packageName>org.jooq.test.h2.generatedclasses</packageName>
|
||||
<directory>./src</directory>
|
||||
</target>
|
||||
</generator>
|
||||
</configuration>
|
||||
@ -41,7 +41,10 @@ import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@ -86,6 +89,45 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormat() throws Exception {
|
||||
jOOQAbstractTest.reset = false;
|
||||
|
||||
// Insert test numbers
|
||||
create().insertInto(T639(), T639_ID(), T639_BIG_DECIMAL())
|
||||
.values(1, null)
|
||||
.values(2, new BigDecimal("0"))
|
||||
.values(3, new BigDecimal("1"))
|
||||
.values(4, new BigDecimal("1.2"))
|
||||
.values(5, new BigDecimal("1.23"))
|
||||
.values(6, new BigDecimal("1.23456789"))
|
||||
.values(7, new BigDecimal("12.3"))
|
||||
.values(8, new BigDecimal("123.4"))
|
||||
.values(9, new BigDecimal("1234.5"))
|
||||
.values(10, new BigDecimal("12345678.9"))
|
||||
.values(11, new BigDecimal("0.1"))
|
||||
.values(12, new BigDecimal("0.12"))
|
||||
.values(13, new BigDecimal("0.123456789"))
|
||||
.execute();
|
||||
|
||||
String format = create().select(T639_ID(), T639_BIG_DECIMAL()).from(T639()).fetch().format();
|
||||
|
||||
// Collect decimal point indexes
|
||||
Set<Integer> decimalPointIndexSet = new HashSet<Integer>();
|
||||
for (String formatLine : format.split("\n")) {
|
||||
// Include only data lines
|
||||
if (formatLine.startsWith("|")) {
|
||||
decimalPointIndexSet.add(formatLine.indexOf("."));
|
||||
}
|
||||
}
|
||||
|
||||
// Remove -1 position
|
||||
decimalPointIndexSet.remove(-1);
|
||||
|
||||
// Check if all decimal points have the same position
|
||||
assertEquals(1, decimalPointIndexSet.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatHTML() throws Exception {
|
||||
List<Field<?>> fields = TBook().getFields();
|
||||
|
||||
@ -1222,6 +1222,11 @@ public abstract class jOOQAbstractTest<
|
||||
new CRUDTests(this).testNonUpdatables();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormat() throws Exception {
|
||||
new FormatTests(this).testFormat();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatHTML() throws Exception {
|
||||
new FormatTests(this).testFormatHTML();
|
||||
|
||||
@ -88,6 +88,7 @@ import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
* @author Ivan Dugic
|
||||
*/
|
||||
class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
|
||||
@ -937,33 +938,73 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
|
||||
@Override
|
||||
public final String format(int maxRecords) {
|
||||
final int MAX_WIDTH = 50;
|
||||
final int COL_MIN_WIDTH = 4;
|
||||
final int COL_MAX_WIDTH = 50;
|
||||
// Numeric columns have greater max width because values are aligned
|
||||
final int NUM_COL_MAX_WIDTH = 100;
|
||||
|
||||
final int MAX_RECORDS = 50;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Map<Field<?>, Integer> widths = new HashMap<Field<?>, Integer>();
|
||||
|
||||
// Initialise widths
|
||||
// Get max decimal places for numeric type columns
|
||||
Map<Field<?>, Integer> decimalPlacesMap = new HashMap<Field<?>, Integer>();
|
||||
for (Field<?> f : getFields()) {
|
||||
widths.put(f, 4);
|
||||
if (Number.class.isAssignableFrom(f.getType())) {
|
||||
List<Integer> decimalPlacesList = new ArrayList<Integer>();
|
||||
|
||||
// Initialize
|
||||
decimalPlacesList.add(0);
|
||||
|
||||
// Collect all decimal places for the column values
|
||||
String value;
|
||||
for (int i = 0; i < min(MAX_RECORDS, size()); i++) {
|
||||
value = format0(getValue(i, f));
|
||||
decimalPlacesList.add(getDecimalPlaces(value));
|
||||
}
|
||||
|
||||
// Find max
|
||||
decimalPlacesMap.put(f, Collections.max(decimalPlacesList));
|
||||
}
|
||||
}
|
||||
|
||||
// Find width for every field to satisfy formatting the first 50 records
|
||||
// Get max column widths
|
||||
Map<Field<?>, Integer> widthMap = new HashMap<Field<?>, Integer>();
|
||||
int colMaxWidth;
|
||||
for (Field<?> f : getFields()) {
|
||||
widths.put(f, min(MAX_WIDTH, max(widths.get(f), f.getName().length())));
|
||||
// Is number column?
|
||||
boolean isNumCol = Number.class.isAssignableFrom(f.getType());
|
||||
|
||||
colMaxWidth = isNumCol ? NUM_COL_MAX_WIDTH : COL_MAX_WIDTH;
|
||||
|
||||
// Collect all widths for the column
|
||||
List<Integer> widthList = new ArrayList<Integer>();
|
||||
|
||||
// Add column name width first
|
||||
widthList.add(min(colMaxWidth, max(COL_MIN_WIDTH, f.getName().length())));
|
||||
|
||||
// Add column values width
|
||||
String value;
|
||||
for (int i = 0; i < min(MAX_RECORDS, size()); i++) {
|
||||
widths.put(f, min(MAX_WIDTH, max(widths.get(f), format0(getValue(i, f)).length())));
|
||||
value = format0(getValue(i, f));
|
||||
// Align number values before width is calculated
|
||||
if (isNumCol) {
|
||||
value = alignNumberValue(decimalPlacesMap.get(f), value);
|
||||
}
|
||||
|
||||
widthList.add(min(colMaxWidth, value.length()));
|
||||
}
|
||||
|
||||
// Find max
|
||||
widthMap.put(f, Collections.max(widthList));
|
||||
}
|
||||
|
||||
// Begin the writing
|
||||
// ---------------------------------------------------------------------
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// Write top line
|
||||
sb.append("+");
|
||||
for (Field<?> f : getFields()) {
|
||||
sb.append(rightPad("", widths.get(f), "-"));
|
||||
sb.append(rightPad("", widthMap.get(f), "-"));
|
||||
sb.append("+");
|
||||
}
|
||||
|
||||
@ -973,20 +1014,20 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
String padded;
|
||||
|
||||
if (Number.class.isAssignableFrom(f.getType())) {
|
||||
padded = leftPad(f.getName(), widths.get(f));
|
||||
padded = leftPad(f.getName(), widthMap.get(f));
|
||||
}
|
||||
else {
|
||||
padded = rightPad(f.getName(), widths.get(f));
|
||||
padded = rightPad(f.getName(), widthMap.get(f));
|
||||
}
|
||||
|
||||
sb.append(abbreviate(padded, widths.get(f)));
|
||||
sb.append(abbreviate(padded, widthMap.get(f)));
|
||||
sb.append("|");
|
||||
}
|
||||
|
||||
// Write separator
|
||||
sb.append("\n+");
|
||||
for (Field<?> f : getFields()) {
|
||||
sb.append(rightPad("", widths.get(f), "-"));
|
||||
sb.append(rightPad("", widthMap.get(f), "-"));
|
||||
sb.append("+");
|
||||
}
|
||||
|
||||
@ -995,16 +1036,21 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
sb.append("\n|");
|
||||
for (Field<?> f : getFields()) {
|
||||
String value = format0(getValue(i, f)).replace("\n", "{lf}").replace("\r", "{cr}");
|
||||
String padded;
|
||||
|
||||
String padded;
|
||||
if (Number.class.isAssignableFrom(f.getType())) {
|
||||
padded = leftPad(value, widths.get(f));
|
||||
// Align number value before left pad
|
||||
value = alignNumberValue(decimalPlacesMap.get(f), value);
|
||||
|
||||
// Left pad
|
||||
padded = leftPad(value, widthMap.get(f));
|
||||
}
|
||||
else {
|
||||
padded = rightPad(value, widths.get(f));
|
||||
// Right pad
|
||||
padded = rightPad(value, widthMap.get(f));
|
||||
}
|
||||
|
||||
sb.append(abbreviate(padded, widths.get(f)));
|
||||
sb.append(abbreviate(padded, widthMap.get(f)));
|
||||
sb.append("|");
|
||||
}
|
||||
}
|
||||
@ -1013,7 +1059,7 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
if (size() > 0) {
|
||||
sb.append("\n+");
|
||||
for (Field<?> f : getFields()) {
|
||||
sb.append(rightPad("", widths.get(f), "-"));
|
||||
sb.append(rightPad("", widthMap.get(f), "-"));
|
||||
sb.append("+");
|
||||
}
|
||||
}
|
||||
@ -1028,6 +1074,34 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String alignNumberValue(Integer columnDecimalPlaces, String value) {
|
||||
if (!"{null}".equals(value) && columnDecimalPlaces != 0) {
|
||||
int decimalPlaces = getDecimalPlaces(value);
|
||||
int rightPadSize = value.length() + columnDecimalPlaces - decimalPlaces;
|
||||
|
||||
if (decimalPlaces == 0) {
|
||||
// If integer value, add one for decimal point
|
||||
value = rightPad(value, rightPadSize + 1);
|
||||
}
|
||||
else {
|
||||
value = rightPad(value, rightPadSize);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private Integer getDecimalPlaces(String value) {
|
||||
int decimalPlaces = 0;
|
||||
|
||||
int dotIndex = value.indexOf(".");
|
||||
if (dotIndex != -1) {
|
||||
decimalPlaces = value.length() - dotIndex - 1;
|
||||
}
|
||||
|
||||
return decimalPlaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String formatHTML() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -1140,6 +1214,10 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
|
||||
else if (value instanceof EnumType) {
|
||||
formatted = ((EnumType) value).getLiteral();
|
||||
}
|
||||
else if (value instanceof Number) {
|
||||
// Remove insignificant zeros
|
||||
formatted = value.toString().replaceAll("(?:(\\..*[^0])0+|\\.0+)$", "$1");
|
||||
}
|
||||
else {
|
||||
formatted = value.toString();
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user