[#2043] Remove generated navigation methods

This commit is contained in:
Lukas Eder 2012-12-22 18:17:05 +01:00
parent 5635339388
commit e71d9444c2
9 changed files with 3 additions and 274 deletions

View File

@ -47,7 +47,6 @@ abstract class AbstractGenerator implements Generator {
boolean generateDeprecated = true;
boolean generateRelations = true;
boolean generateNavigationMethods = true;
boolean generateInstanceFields = true;
boolean generateGeneratedAnnotation = true;
boolean generateRecords = true;
@ -95,16 +94,6 @@ abstract class AbstractGenerator implements Generator {
return generateInstanceFields;
}
@Override
public boolean generateNavigationMethods() {
return generateNavigationMethods;
}
@Override
public void setGenerateNavigationMethods(boolean generateNavigationMethods) {
this.generateNavigationMethods = generateNavigationMethods;
}
@Override
public void setGenerateInstanceFields(boolean generateInstanceFields) {
this.generateInstanceFields = generateInstanceFields;

View File

@ -353,8 +353,6 @@ public class GenerationTool {
g.setGenerate(new Generate());
if (g.getGenerate().isRelations() != null)
generator.setGenerateRelations(g.getGenerate().isRelations());
if (g.getGenerate().isNavigationMethods() != null)
generator.setGenerateNavigationMethods(g.getGenerate().isNavigationMethods());
if (g.getGenerate().isDeprecated() != null)
generator.setGenerateDeprecated(g.getGenerate().isDeprecated());
if (g.getGenerate().isInstanceFields() != null)

View File

@ -80,16 +80,6 @@ public interface Generator {
*/
void setGenerateRelations(boolean generateRelations);
/**
* Whether foreign key navigation methods should be generated
*/
boolean generateNavigationMethods();
/**
* Whether foreign key navigation methods should be generated
*/
void setGenerateNavigationMethods(boolean generateNavigationMethods);
/**
* Whether instance fields should be generated (as opposed to static fields)
*/

View File

@ -44,9 +44,7 @@ import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.jooq.AggregateFunction;
import org.jooq.Configuration;
@ -58,7 +56,6 @@ import org.jooq.ForeignKey;
import org.jooq.Identity;
import org.jooq.Parameter;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.Row;
import org.jooq.Sequence;
import org.jooq.Table;
@ -147,7 +144,6 @@ public class JavaGenerator extends AbstractGenerator {
log.info(" instance fields", generateInstanceFields());
log.info(" JPA annotations", generateJPAAnnotations());
log.info(" validation annotations", generateValidationAnnotations());
log.info(" navigation methods", generateNavigationMethods());
log.info(" records", generateRecords()
+ ((!generateRecords && generateDaos) ? " (forced to true because of <daos/>)" : ""));
log.info(" pojos", generatePojos()
@ -530,14 +526,6 @@ public class JavaGenerator extends AbstractGenerator {
out.tab(1).println("}");
}
if (generateRelations() && generateNavigationMethods()) {
out.tab(1).header("Foreign key navigation methods");
for (ColumnDefinition column : table.getColumns()) {
printNavigateMethods(out, column);
}
}
if (generateRelations() && key != null) {
int keyDegree = key.getKeyColumns().size();
@ -2079,155 +2067,6 @@ public class JavaGenerator extends AbstractGenerator {
out.tab(1).println("public static final %s %s = new %s();", className, identifier, className);
}
protected void printNavigateMethods(JavaWriter out, ColumnDefinition column) {
List<UniqueKeyDefinition> uniqueKeys = column.getUniqueKeys();
// Print references from this column's unique keys to all
// corresponding foreign keys.
// e.g. in TAuthorRecord, print getTBooks()
// -----------------------------------------------------------------
Set<String> fetchMethodNames = new HashSet<String>();
for (UniqueKeyDefinition uniqueKey : uniqueKeys) {
if (out.printOnlyOnce(uniqueKey)) {
for (ForeignKeyDefinition foreignKey : uniqueKey.getForeignKeys()) {
printFetchFKList(out, foreignKey, fetchMethodNames);
}
}
}
// Print references from this foreign key to its related primary key
// E.g. in TBookRecord print getTAuthor()
// -----------------------------------------------------------------
for (ForeignKeyDefinition foreignKey : column.getForeignKeys()) {
if (out.printOnlyOnce(foreignKey)) {
printFetchFK(out, column, foreignKey);
}
}
}
protected void printFetchFK(JavaWriter out, ColumnDefinition column, ForeignKeyDefinition foreignKey) {
// #64 - If the foreign key does not match the referenced key, it
// is most likely because it references a non-primary unique key
// Skip code generation for this foreign key
// #69 - Should resolve this issue more thoroughly.
if (foreignKey.getReferencedColumns().size() != foreignKey.getKeyColumns().size()) {
log.warn("Foreign key mismatch", foreignKey.getName() + " does not match its primary key! No code is generated for this key. See trac tickets #64 and #69");
return;
}
final TableDefinition referenced = foreignKey.getReferencedTable();
final TableDefinition referencing = foreignKey.getKeyTable();
final String referencedId = getStrategy().getFullJavaIdentifier(referenced);
final String referencedType = getStrategy().getFullJavaClassName(referenced, Mode.RECORD);
final String referencedClassName = getStrategy().getJavaClassName(referenced);
// [#350] - Disambiguate multiple foreign keys referencing
// the same table
List<String> disambiguation = list(foreignKey.countSimilarReferences() > 1
? getStrategy().getJavaClassName(column)
: null);
out.tab(1).javadoc("Fetch a record from <code>%s</code> referenced from <code>%s</code> through <code>%s</code>",
referenced.getQualifiedOutputName(),
referencing.getQualifiedOutputName(),
foreignKey.getQualifiedOutputName());
out.tab(1).println("public %s fetch%s[[before=By][%s]]() {", referencedType, referencedClassName, disambiguation);
out.tab(2).println("return create()");
out.tab(3).println(".selectFrom(%s)", referencedId);
String connector = "where";
for (int i = 0; i < foreignKey.getReferencedColumns().size(); i++) {
final String ukId = getStrategy().getFullJavaIdentifier(foreignKey.getReferencedColumns().get(i));
final String fkId = getStrategy().getFullJavaIdentifier(foreignKey.getKeyColumns().get(i));
// Convert foreign key value, if there is a type mismatch
DataTypeDefinition foreignType = foreignKey.getKeyColumns().get(i).getType();
DataTypeDefinition primaryType = foreignKey.getReferencedColumns().get(i).getType();
List<String> conversion = list(!match(foreignType, primaryType)
? getSimpleJavaType(foreignKey.getReferencedColumns().get(i).getType())
: null);
out.tab(3).println(".%s(%s.equal(getValue(%s[[before=, ][after=.class][%s]])))", connector, ukId, fkId, conversion);
connector = "and";
}
out.println("\t\t\t.fetchOne();");
out.println("\t}");
}
protected void printFetchFKList(JavaWriter out, ForeignKeyDefinition foreignKey, Set<String> fetchMethodNames) {
// [#64] - If the foreign key does not match the referenced key, it
// is most likely because it references a non-primary unique key
// Skip code generation for this foreign key
// [#69] - Should resolve this issue more thoroughly.
if (foreignKey.getReferencedColumns().size() != foreignKey.getKeyColumns().size()) {
log.warn("Foreign key mismatch", foreignKey.getName() + " does not match its primary key! No code is generated for this key. See trac tickets #64 and #69");
return;
}
final TableDefinition referencing = foreignKey.getKeyTable();
final TableDefinition referenced = foreignKey.getReferencedTable();
final UniqueKeyDefinition uniqueKey = foreignKey.getReferencedKey();
final String referencingType = getStrategy().getFullJavaClassName(referencing, Mode.RECORD);
final String referencingId = getStrategy().getFullJavaIdentifier(referencing);
final StringBuilder method = new StringBuilder();
method.append("fetch");
method.append(getStrategy().getJavaClassName(referencing));
// [#352] - Disambiguate foreign key navigation directions
method.append("List");
// [#350] - Disambiguate multiple foreign keys referencing
// the same table
if (foreignKey.countSimilarReferences() > 1) {
method.append("By");
method.append(getStrategy().getJavaClassName(foreignKey.getKeyColumns().get(0)));
}
// [#1270] - Disambiguate identical foreign keys
if (fetchMethodNames.contains(method.toString())) {
log.warn("Duplicate foreign key", foreignKey.getName() + " has the same properties as another foreign key! No code is generated for this key. See trac ticket #1270");
return;
}
else {
fetchMethodNames.add(method.toString());
}
out.tab(1).javadoc("Fetch a list of <code>%s</code> referencing this <code>%s</code>", referencing.getQualifiedOutputName(), referenced.getQualifiedOutputName());
out.tab(1).println("public %s<%s> %s() {", Result.class, referencingType, method);
out.tab(2).println("return create()");
out.tab(3).println(".selectFrom(%s)", referencingId);
String connector = "where";
for (int i = 0; i < foreignKey.getReferencedColumns().size(); i++) {
final String fkId = getStrategy().getFullJavaIdentifier(foreignKey.getKeyColumns().get(i));
final String ukId = getStrategy().getFullJavaIdentifier(uniqueKey.getKeyColumns().get(i));
// Convert foreign key value, if there is a type mismatch
DataTypeDefinition foreignType = foreignKey.getKeyColumns().get(i).getType();
DataTypeDefinition primaryType = uniqueKey.getKeyColumns().get(i).getType();
List<String> conversion = list(!match(foreignType, primaryType)
? getSimpleJavaType(foreignKey.getKeyColumns().get(i).getType())
: null);
out.tab(3).println(".%s(%s.equal(getValue(%s[[before=, ][after=.class][%s]])))", connector, fkId, ukId, conversion);
connector = "and";
}
out.tab(3).println(".fetch();");
out.tab(1).println("}");
}
protected void printClassJavadoc(JavaWriter out, Definition definition) {
printClassJavadoc(out, definition.getComment());
}

View File

@ -2,8 +2,6 @@ package org.jooq.util;
import java.io.File;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
/**
@ -18,12 +16,8 @@ public class JavaWriter extends GeneratorWriter<JavaWriter> {
private static final String SERIAL_STATEMENT = "__SERIAL_STATEMENT__";
private final Set<Object> alreadyPrinted;
public JavaWriter(File file) {
super(file);
this.alreadyPrinted = new HashSet<Object>();
}
public JavaWriter print(Class<?> clazz) {
@ -75,15 +69,6 @@ public class JavaWriter extends GeneratorWriter<JavaWriter> {
return this;
}
public boolean printOnlyOnce(Object object) {
if (!alreadyPrinted.contains(object)) {
alreadyPrinted.add(object);
return true;
}
return false;
}
public void printSerial() {
println();
println("\tprivate static final long serialVersionUID = %s;", SERIAL_STATEMENT);

View File

@ -296,13 +296,6 @@
-->
<element name="relations" type="boolean" default="true" minOccurs="0" maxOccurs="1" />
<!--
Generate navigation methods to navigate foreign key relationships
directly from Record classes. This is only relevant if relations
is set to true, too
-->
<element name="navigationMethods" type="boolean" default="true" minOccurs="0" maxOccurs="1" />
<!-- Generate deprecated code for backwards compatibility -->
<element name="deprecated" type="boolean" default="true" minOccurs="0" maxOccurs="1" />

View File

@ -47,17 +47,12 @@ import static org.jooq.impl.Factory.table;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.jooq.Field;
import org.jooq.InsertQuery;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Record2;
import org.jooq.Record3;
@ -235,68 +230,6 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
assertEquals(null, create().fetchOne(TAuthor(), TAuthor_FIRST_NAME().equal("Erich")));
}
@Test
public void testRelations() throws Exception {
if (getDialect() == SQLDialect.SQLITE) {
log.info("SKIPPING", "referentials test");
return;
}
jOOQAbstractTest.reset = false;
// Get the book 1984
B book1984 = create().fetchOne(TBook(), TBook_TITLE().equal("1984"));
// Navigate to the book's author
Record authorOrwell = (Record) invoke(book1984, "fetchTAuthorByAuthorId");
assertEquals("Orwell", authorOrwell.getValue(TAuthor_LAST_NAME()));
// Navigate back to the author's books
List<?> books1 = (List<?>) invoke(authorOrwell, "fetchTBookListByAuthorId");
assertEquals(2, books1.size());
// Navigate through m:n relationships of books
List<Object> booksToBookStores = new ArrayList<Object>();
for (Object b : books1) {
booksToBookStores.addAll((List<?>) invoke(b, "fetchTBookToBookStoreList"));
}
assertEquals(3, booksToBookStores.size());
// Navigate to book stores
Set<String> bookStoreNames = new TreeSet<String>();
List<Object> bookStores = new ArrayList<Object>();
for (Object b : booksToBookStores) {
Object store = invoke(b, "fetchTBookStore");
bookStores.add(store);
bookStoreNames.add((String) invoke(store, "getName"));
}
assertEquals(Arrays.asList("Ex Libris", "Orell Füssli"), new ArrayList<String>(bookStoreNames));
// Navigate through m:n relationships of book stores
booksToBookStores = new ArrayList<Object>();
for (Object b : bookStores) {
booksToBookStores.addAll((List<?>) invoke(b, "fetchTBookToBookStoreList"));
}
// Navigate back to books
Set<String> book2Names = new TreeSet<String>();
List<Object> books2 = new ArrayList<Object>();
for (Object b : booksToBookStores) {
Object book = invoke(b, "fetchTBook");
books2.add(book);
book2Names.add((String) invoke(book, "getTitle"));
}
assertEquals(Arrays.asList("1984", "Animal Farm", "O Alquimista"), new ArrayList<String>(book2Names));
// Navigate back to authors
Set<String> authorNames = new TreeSet<String>();
for (Object b : books2) {
Object author = invoke(b, "fetchTAuthorByAuthorId");
authorNames.add((String) invoke(author, "getLastName"));
}
assertEquals(Arrays.asList("Coelho", "Orwell"), new ArrayList<String>(authorNames));
}
@Test
public void testUpdatablesCopy() throws Exception {
if (TTriggers() == null) {

View File

@ -145,7 +145,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
assertEquals(sequence, schema.getSequence(sequence.getName()));
}
int tables = 17;
int tables = 18;
// The additional T_DIRECTORY table for recursive queries
if (supportsRecursiveQueries()) {

View File

@ -9209,6 +9209,8 @@ for (Record record : create().select(
<li>Various API changes have been done</li>
</ul>
<h3>No more navigation methods and "foreign key setters"</h3>
<h3>Object renames</h3>
<ul>
<li>jOOU</li>