mirror of
https://github.com/apache/sqoop.git
synced 2025-05-05 00:00:22 +08:00
SQOOP-158. Additional methods for generated classes.
Adding setter-methods and a field-based equals-implementation to the generated classes. These new methods enhance the usage of the generated classes. (Michael Häusler via ahmed) From: Ahmed Radwan <ahmed@cloudera.com> git-svn-id: https://svn.apache.org/repos/asf/incubator/sqoop/trunk@1150037 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
dfd9021662
commit
0870f9499a
@ -426,13 +426,14 @@ private String rpcSetterForMaybeNull(String javaType, String outputObj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a member field and getter method for each column.
|
* Generate a member field, getter, setter and with method for each column.
|
||||||
* @param columnTypes - mapping from column names to sql types
|
* @param columnTypes - mapping from column names to sql types
|
||||||
* @param colNames - ordered list of column names for table.
|
* @param colNames - ordered list of column names for table
|
||||||
|
* @param className - name of the generated class
|
||||||
* @param sb - StringBuilder to append code to
|
* @param sb - StringBuilder to append code to
|
||||||
*/
|
*/
|
||||||
private void generateFields(Map<String, Integer> columnTypes,
|
private void generateFields(Map<String, Integer> columnTypes,
|
||||||
String [] colNames, StringBuilder sb) {
|
String [] colNames, String className, StringBuilder sb) {
|
||||||
|
|
||||||
for (String col : colNames) {
|
for (String col : colNames) {
|
||||||
int sqlType = columnTypes.get(col);
|
int sqlType = columnTypes.get(col);
|
||||||
@ -446,9 +447,51 @@ private void generateFields(Map<String, Integer> columnTypes,
|
|||||||
sb.append(" public " + javaType + " get_" + col + "() {\n");
|
sb.append(" public " + javaType + " get_" + col + "() {\n");
|
||||||
sb.append(" return " + col + ";\n");
|
sb.append(" return " + col + ";\n");
|
||||||
sb.append(" }\n");
|
sb.append(" }\n");
|
||||||
|
sb.append(" public void set_" + col + "(" + javaType + " " + col
|
||||||
|
+ ") {\n");
|
||||||
|
sb.append(" this." + col + " = " + col + ";\n");
|
||||||
|
sb.append(" }\n");
|
||||||
|
sb.append(" public " + className + " with_" + col + "(" + javaType + " "
|
||||||
|
+ col + ") {\n");
|
||||||
|
sb.append(" this." + col + " = " + col + ";\n");
|
||||||
|
sb.append(" return this;\n");
|
||||||
|
sb.append(" }\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an equals method that compares the fields for each column.
|
||||||
|
* @param columnTypes - mapping from column names to sql types
|
||||||
|
* @param colNames - ordered list of column names for table
|
||||||
|
* @param className - name of the generated class
|
||||||
|
* @param sb - StringBuilder to append code to
|
||||||
|
*/
|
||||||
|
private void generateEquals(Map<String, Integer> columnTypes,
|
||||||
|
String [] colNames, String className, StringBuilder sb) {
|
||||||
|
|
||||||
|
sb.append(" public boolean equals(Object o) {\n");
|
||||||
|
sb.append(" if (this == o) {\n");
|
||||||
|
sb.append(" return true;\n");
|
||||||
|
sb.append(" }\n");
|
||||||
|
sb.append(" if (!(o instanceof " + className + ")) {\n");
|
||||||
|
sb.append(" return false;\n");
|
||||||
|
sb.append(" }\n");
|
||||||
|
sb.append(" " + className + " that = (" + className + ") o;\n");
|
||||||
|
sb.append(" boolean equal = true;\n");
|
||||||
|
for (String col : colNames) {
|
||||||
|
int sqlType = columnTypes.get(col);
|
||||||
|
String javaType = connManager.toJavaType(sqlType);
|
||||||
|
if (null == javaType) {
|
||||||
|
LOG.error("Cannot resolve SQL type " + sqlType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sb.append(" equal = equal && (this." + col + " == null ? that." + col
|
||||||
|
+ " == null : this." + col + ".equals(that." + col + "));\n");
|
||||||
|
}
|
||||||
|
sb.append(" return equal;\n");
|
||||||
|
sb.append(" }\n");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the readFields() method used by the database.
|
* Generate the readFields() method used by the database.
|
||||||
* @param columnTypes - mapping from column names to sql types
|
* @param columnTypes - mapping from column names to sql types
|
||||||
@ -1180,7 +1223,8 @@ private StringBuilder generateClassForColumns(
|
|||||||
sb.append(
|
sb.append(
|
||||||
" public int getClassFormatVersion() { return PROTOCOL_VERSION; }\n");
|
" public int getClassFormatVersion() { return PROTOCOL_VERSION; }\n");
|
||||||
sb.append(" protected ResultSet __cur_result_set;\n");
|
sb.append(" protected ResultSet __cur_result_set;\n");
|
||||||
generateFields(columnTypes, colNames, sb);
|
generateFields(columnTypes, colNames, className, sb);
|
||||||
|
generateEquals(columnTypes, colNames, className, sb);
|
||||||
generateDbRead(columnTypes, colNames, sb);
|
generateDbRead(columnTypes, colNames, sb);
|
||||||
generateLoadLargeObjects(columnTypes, colNames, sb);
|
generateLoadLargeObjects(columnTypes, colNames, sb);
|
||||||
generateDbWrite(columnTypes, dbWriteColNames, sb);
|
generateDbWrite(columnTypes, dbWriteColNames, sb);
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@ -41,6 +43,7 @@
|
|||||||
import com.cloudera.sqoop.testutil.HsqldbTestServer;
|
import com.cloudera.sqoop.testutil.HsqldbTestServer;
|
||||||
import com.cloudera.sqoop.testutil.ImportJobTestCase;
|
import com.cloudera.sqoop.testutil.ImportJobTestCase;
|
||||||
import com.cloudera.sqoop.tool.ImportTool;
|
import com.cloudera.sqoop.tool.ImportTool;
|
||||||
|
import com.cloudera.sqoop.util.ClassLoaderStack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that the ClassWriter generates Java classes based on the given table,
|
* Test that the ClassWriter generates Java classes based on the given table,
|
||||||
@ -118,8 +121,9 @@ public void tearDown() {
|
|||||||
/**
|
/**
|
||||||
* Run a test to verify that we can generate code and it emits the output
|
* Run a test to verify that we can generate code and it emits the output
|
||||||
* files where we expect them.
|
* files where we expect them.
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
private void runGenerationTest(String [] argv, String classNameToCheck) {
|
private File runGenerationTest(String [] argv, String classNameToCheck) {
|
||||||
File codeGenDirFile = new File(CODE_GEN_DIR);
|
File codeGenDirFile = new File(CODE_GEN_DIR);
|
||||||
File classGenDirFile = new File(JAR_GEN_DIR);
|
File classGenDirFile = new File(JAR_GEN_DIR);
|
||||||
|
|
||||||
@ -195,6 +199,7 @@ private void runGenerationTest(String [] argv, String classNameToCheck) {
|
|||||||
+ ".class in jar file", foundCompiledClass);
|
+ ".class in jar file", foundCompiledClass);
|
||||||
|
|
||||||
LOG.debug("Found class in jar - test success!");
|
LOG.debug("Found class in jar - test success!");
|
||||||
|
return jarFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,5 +339,87 @@ public void testWeirdColumnNames() throws SQLException {
|
|||||||
runGenerationTest(argv, OVERRIDE_PACKAGE_NAME + "."
|
runGenerationTest(argv, OVERRIDE_PACKAGE_NAME + "."
|
||||||
+ HsqldbTestServer.getTableName());
|
+ HsqldbTestServer.getTableName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the generated equals method.
|
||||||
|
* @throws IOException
|
||||||
|
* @throws ClassNotFoundException
|
||||||
|
* @throws IllegalAccessException
|
||||||
|
* @throws InstantiationException
|
||||||
|
* @throws NoSuchMethodException
|
||||||
|
* @throws SecurityException
|
||||||
|
* @throws InvocationTargetException
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEqualsMethod() throws IOException, ClassNotFoundException,
|
||||||
|
InstantiationException, IllegalAccessException, NoSuchMethodException,
|
||||||
|
InvocationTargetException {
|
||||||
|
|
||||||
|
// Set the option strings in an "argv" to redirect our srcdir and bindir
|
||||||
|
String [] argv = {
|
||||||
|
"--bindir",
|
||||||
|
JAR_GEN_DIR,
|
||||||
|
"--outdir",
|
||||||
|
CODE_GEN_DIR,
|
||||||
|
"--class-name",
|
||||||
|
OVERRIDE_CLASS_AND_PACKAGE_NAME,
|
||||||
|
};
|
||||||
|
|
||||||
|
File ormJarFile = runGenerationTest(argv, OVERRIDE_CLASS_AND_PACKAGE_NAME);
|
||||||
|
ClassLoader prevClassLoader = ClassLoaderStack.addJarFile(
|
||||||
|
ormJarFile.getCanonicalPath(),
|
||||||
|
OVERRIDE_CLASS_AND_PACKAGE_NAME);
|
||||||
|
Class tableClass = Class.forName(
|
||||||
|
OVERRIDE_CLASS_AND_PACKAGE_NAME,
|
||||||
|
true,
|
||||||
|
Thread.currentThread().getContextClassLoader());
|
||||||
|
Method setterIntField1 =
|
||||||
|
tableClass.getMethod("set_INTFIELD1", Integer.class);
|
||||||
|
Method setterIntField2 =
|
||||||
|
tableClass.getMethod("set_INTFIELD2", Integer.class);
|
||||||
|
Method equalsImplementation = tableClass.getMethod("equals", Object.class);
|
||||||
|
|
||||||
|
Object instance1 = tableClass.newInstance();
|
||||||
|
Object instance2 = tableClass.newInstance();
|
||||||
|
|
||||||
|
// test reflexivity
|
||||||
|
assertTrue((Boolean) equalsImplementation.invoke(instance1, instance1));
|
||||||
|
|
||||||
|
// test equality for uninitialized fields
|
||||||
|
assertTrue((Boolean) equalsImplementation.invoke(instance1, instance2));
|
||||||
|
|
||||||
|
// test symmetry
|
||||||
|
assertTrue((Boolean) equalsImplementation.invoke(instance2, instance1));
|
||||||
|
|
||||||
|
// test reflexivity with initialized fields
|
||||||
|
setterIntField1.invoke(instance1, new Integer(1));
|
||||||
|
setterIntField2.invoke(instance1, new Integer(2));
|
||||||
|
assertTrue((Boolean) equalsImplementation.invoke(instance1, instance1));
|
||||||
|
|
||||||
|
// test difference in both fields
|
||||||
|
setterIntField1.invoke(instance2, new Integer(3));
|
||||||
|
setterIntField2.invoke(instance2, new Integer(4));
|
||||||
|
assertFalse((Boolean) equalsImplementation.invoke(instance1, instance2));
|
||||||
|
|
||||||
|
// test difference in second field
|
||||||
|
setterIntField1.invoke(instance2, new Integer(1));
|
||||||
|
setterIntField2.invoke(instance2, new Integer(3));
|
||||||
|
assertFalse((Boolean) equalsImplementation.invoke(instance1, instance2));
|
||||||
|
|
||||||
|
// test difference in first field
|
||||||
|
setterIntField1.invoke(instance2, new Integer(3));
|
||||||
|
setterIntField2.invoke(instance2, new Integer(2));
|
||||||
|
assertFalse((Boolean) equalsImplementation.invoke(instance1, instance2));
|
||||||
|
|
||||||
|
// test equality for initialized fields
|
||||||
|
setterIntField1.invoke(instance2, new Integer(1));
|
||||||
|
setterIntField2.invoke(instance2, new Integer(2));
|
||||||
|
assertTrue((Boolean) equalsImplementation.invoke(instance1, instance2));
|
||||||
|
|
||||||
|
if (null != prevClassLoader) {
|
||||||
|
ClassLoaderStack.setCurrentClassLoader(prevClassLoader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user