Browse Source

Use column label from ResultSetMetaData when importing. Fixes #152

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1268 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.2.3
James Ahlborn 5 years ago
parent
commit
a06385c7c9

+ 3
- 0
src/changes/changes.xml View File

<action dev="jahlborn" type="fix"> <action dev="jahlborn" type="fix">
Fix parsing of escaped double quotes in expressions. Fix parsing of escaped double quotes in expressions.
</action> </action>
<action dev="jahlborn" type="fix" system="SourceForge2" issue="152">
Use column label from ResultSetMetaData when importing.
</action>
</release> </release>
<release version="2.2.2" date="2019-01-05"> <release version="2.2.2" date="2019-01-05">
<action dev="jahlborn" type="fix" system="SourceForge2" issue="151"> <action dev="jahlborn" type="fix" system="SourceForge2" issue="151">

+ 44
- 44
src/main/java/com/healthmarketscience/jackcess/util/ImportUtil.java View File

* @author James Ahlborn * @author James Ahlborn
* @usage _general_class_ * @usage _general_class_
*/ */
public class ImportUtil
public class ImportUtil
{ {
/** Batch commit size for copying other result sets into this database */ /** Batch commit size for copying other result sets into this database */
private static final int COPY_TABLE_BATCH_SIZE = 200; private static final int COPY_TABLE_BATCH_SIZE = 200;


/** the platform line separator */ /** the platform line separator */
static final String LINE_SEPARATOR = System.getProperty("line.separator"); static final String LINE_SEPARATOR = System.getProperty("line.separator");
private ImportUtil() {} private ImportUtil() {}


/** /**
{ {
List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>(); List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
for (int i = 1; i <= md.getColumnCount(); i++) { for (int i = 1; i <= md.getColumnCount(); i++) {
ColumnBuilder column = new ColumnBuilder(md.getColumnName(i))
ColumnBuilder column = new ColumnBuilder(md.getColumnLabel(i))
.escapeName(); .escapeName();
int lengthInUnits = md.getColumnDisplaySize(i); int lengthInUnits = md.getColumnDisplaySize(i);
column.setSQLType(md.getColumnType(i), lengthInUnits); column.setSQLType(md.getColumnType(i), lengthInUnits);
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importResultSet(source, db, name, SimpleImportFilter.INSTANCE);} * {@code importResultSet(source, db, name, SimpleImportFilter.INSTANCE);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param source ResultSet to copy from * @param source ResultSet to copy from
* *
{ {
return importResultSet(source, db, name, SimpleImportFilter.INSTANCE); return importResultSet(source, db, name, SimpleImportFilter.INSTANCE);
} }
/** /**
* Copy an existing JDBC ResultSet into a new table in this database. * Copy an existing JDBC ResultSet into a new table in this database.
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importResultSet(source, db, name, filter, false);} * {@code importResultSet(source, db, name, filter, false);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param source ResultSet to copy from * @param source ResultSet to copy from
* @param filter valid import filter * @param filter valid import filter
{ {
return importResultSet(source, db, name, filter, false); return importResultSet(source, db, name, filter, false);
} }
/** /**
* Copy an existing JDBC ResultSet into a new (or optionally existing) table * Copy an existing JDBC ResultSet into a new (or optionally existing) table
* in this database. * in this database.
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param source ResultSet to copy from * @param source ResultSet to copy from
* @param filter valid import filter * @param filter valid import filter
* name * name
* *
* @return the name of the imported table * @return the name of the imported table
*
*
* @see Builder * @see Builder
*/ */
public static String importResultSet(ResultSet source, Database db, public static String importResultSet(ResultSet source, Database db,


return table.getName(); return table.getName();
} }
/** /**
* Copy a delimited text file into a new table in this database. * Copy a delimited text file into a new table in this database.
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importFile(f, name, db, delim, SimpleImportFilter.INSTANCE);} * {@code importFile(f, name, db, delim, SimpleImportFilter.INSTANCE);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param f Source file to import * @param f Source file to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importFile(f, name, db, delim, "'", filter, false);} * {@code importFile(f, name, db, delim, "'", filter, false);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param f Source file to import * @param f Source file to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importReader(new BufferedReader(new FileReader(f)), db, name, delim, "'", filter, useExistingTable, true);} * {@code importReader(new BufferedReader(new FileReader(f)), db, name, delim, "'", filter, useExistingTable, true);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param f Source file to import * @param f Source file to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* @see #importReader(BufferedReader,Database,String,String,ImportFilter,boolean) * @see #importReader(BufferedReader,Database,String,String,ImportFilter,boolean)
* @see Builder * @see Builder
*/ */
public static String importFile(File f, Database db, String name,
String delim, char quote,
public static String importFile(File f, Database db, String name,
String delim, char quote,
ImportFilter filter, ImportFilter filter,
boolean useExistingTable) boolean useExistingTable)
throws IOException throws IOException
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importReader(new BufferedReader(new FileReader(f)), db, name, delim, "'", filter, useExistingTable, header);} * {@code importReader(new BufferedReader(new FileReader(f)), db, name, delim, "'", filter, useExistingTable, header);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param f Source file to import * @param f Source file to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* @see #importReader(BufferedReader,Database,String,String,char,ImportFilter,boolean,boolean) * @see #importReader(BufferedReader,Database,String,String,char,ImportFilter,boolean,boolean)
* @see Builder * @see Builder
*/ */
public static String importFile(File f, Database db, String name,
String delim, char quote,
public static String importFile(File f, Database db, String name,
String delim, char quote,
ImportFilter filter, ImportFilter filter,
boolean useExistingTable, boolean useExistingTable,
boolean header) boolean header)
BufferedReader in = null; BufferedReader in = null;
try { try {
in = new BufferedReader(new FileReader(f)); in = new BufferedReader(new FileReader(f));
return importReader(in, db, name, delim, quote, filter,
return importReader(in, db, name, delim, quote, filter,
useExistingTable, header); useExistingTable, header);
} finally { } finally {
ByteUtil.closeQuietly(in); ByteUtil.closeQuietly(in);
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importReader(in, db, name, delim, SimpleImportFilter.INSTANCE);} * {@code importReader(in, db, name, delim, SimpleImportFilter.INSTANCE);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param in Source reader to import * @param in Source reader to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* @see #importReader(BufferedReader,Database,String,String,ImportFilter) * @see #importReader(BufferedReader,Database,String,String,ImportFilter)
* @see Builder * @see Builder
*/ */
public static String importReader(BufferedReader in, Database db,
public static String importReader(BufferedReader in, Database db,
String name, String delim) String name, String delim)
throws IOException throws IOException
{ {
return importReader(in, db, name, delim, SimpleImportFilter.INSTANCE); return importReader(in, db, name, delim, SimpleImportFilter.INSTANCE);
} }
/** /**
* Copy a delimited text file into a new table in this database. * Copy a delimited text file into a new table in this database.
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importReader(in, db, name, delim, filter, false);} * {@code importReader(in, db, name, delim, filter, false);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param in Source reader to import * @param in Source reader to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* @see #importReader(BufferedReader,Database,String,String,ImportFilter,boolean) * @see #importReader(BufferedReader,Database,String,String,ImportFilter,boolean)
* @see Builder * @see Builder
*/ */
public static String importReader(BufferedReader in, Database db,
public static String importReader(BufferedReader in, Database db,
String name, String delim, String name, String delim,
ImportFilter filter) ImportFilter filter)
throws IOException throws IOException
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importReader(in, db, name, delim, '"', filter, false);} * {@code importReader(in, db, name, delim, '"', filter, false);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param in Source reader to import * @param in Source reader to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* name * name
* *
* @return the name of the imported table * @return the name of the imported table
*
*
* @see Builder * @see Builder
*/ */
public static String importReader(BufferedReader in, Database db,
public static String importReader(BufferedReader in, Database db,
String name, String delim, String name, String delim,
ImportFilter filter,
ImportFilter filter,
boolean useExistingTable) boolean useExistingTable)
throws IOException throws IOException
{ {
* <p> * <p>
* Equivalent to: * Equivalent to:
* {@code importReader(in, db, name, delim, '"', filter, useExistingTable, true);} * {@code importReader(in, db, name, delim, '"', filter, useExistingTable, true);}
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param in Source reader to import * @param in Source reader to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* name * name
* *
* @return the name of the imported table * @return the name of the imported table
*
*
* @see Builder * @see Builder
*/ */
public static String importReader(BufferedReader in, Database db,
public static String importReader(BufferedReader in, Database db,
String name, String delim, char quote, String name, String delim, char quote,
ImportFilter filter, ImportFilter filter,
boolean useExistingTable) boolean useExistingTable)
throws IOException throws IOException
{ {
return importReader(in, db, name, delim, quote, filter, useExistingTable,
return importReader(in, db, name, delim, quote, filter, useExistingTable,
true); true);
} }


/** /**
* Copy a delimited text file into a new (or optionally exixsting) table in * Copy a delimited text file into a new (or optionally exixsting) table in
* this database. * this database.
*
*
* @param name Name of the new table to create * @param name Name of the new table to create
* @param in Source reader to import * @param in Source reader to import
* @param delim Regular expression representing the delimiter string. * @param delim Regular expression representing the delimiter string.
* valid if useExistingTable is {@code true} * valid if useExistingTable is {@code true}
* *
* @return the name of the imported table * @return the name of the imported table
*
*
* @see Builder * @see Builder
*/ */
public static String importReader(BufferedReader in, Database db,
public static String importReader(BufferedReader in, Database db,
String name, String delim, char quote, String name, String delim, char quote,
ImportFilter filter, ImportFilter filter,
boolean useExistingTable, boolean header) boolean useExistingTable, boolean header)


List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>(); List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
Object[] columnNames = splitLine(line, delimPat, quote, in, 0); Object[] columnNames = splitLine(line, delimPat, quote, in, 0);
for (int i = 0; i < columnNames.length; i++) { for (int i = 0; i < columnNames.length; i++) {
columns.add(new ColumnBuilder((String)columnNames[i], DataType.TEXT) columns.add(new ColumnBuilder((String)columnNames[i], DataType.TEXT)
.escapeName() .escapeName()
} }


table = createUniqueTable(db, name, columns, null, filter); table = createUniqueTable(db, name, columns, null, filter);
// the first row was a header row // the first row was a header row
header = true; header = true;
} }


List<Object[]> rows = new ArrayList<Object[]>(COPY_TABLE_BATCH_SIZE); List<Object[]> rows = new ArrayList<Object[]>(COPY_TABLE_BATCH_SIZE);
int numColumns = table.getColumnCount(); int numColumns = table.getColumnCount();
if(!header) { if(!header) {
// first line is _not_ a header line // first line is _not_ a header line
Object[] data = splitLine(line, delimPat, quote, in, numColumns); Object[] data = splitLine(line, delimPat, quote, in, numColumns);
data = filter.filterRow(data); data = filter.filterRow(data);
if(data != null) { if(data != null) {
rows.add(data); rows.add(data);
}
}
} }


while ((line = in.readLine()) != null) while ((line = in.readLine()) != null)
idx = endIdx + 1; idx = endIdx + 1;


} else { } else {
// done // done
idx = endIdx; idx = endIdx;
break; break;
*/ */
private static Table createUniqueTable(Database db, String name, private static Table createUniqueTable(Database db, String name,
List<ColumnBuilder> columns, List<ColumnBuilder> columns,
ResultSetMetaData md,
ResultSetMetaData md,
ImportFilter filter) ImportFilter filter)
throws IOException, SQLException throws IOException, SQLException
{ {
while(db.getTable(name) != null) { while(db.getTable(name) != null) {
name = baseName + (counter++); name = baseName + (counter++);
} }
return new TableBuilder(name) return new TableBuilder(name)
.addColumns(filter.filterColumns(columns, md)) .addColumns(filter.filterColumns(columns, md))
.toTable(db); .toTable(db);
public String importResultSet(ResultSet source) public String importResultSet(ResultSet source)
throws SQLException, IOException throws SQLException, IOException
{ {
return ImportUtil.importResultSet(source, _db, _tableName, _filter,
return ImportUtil.importResultSet(source, _db, _tableName, _filter,
_useExistingTable); _useExistingTable);
} }


* @see ImportUtil#importReader(BufferedReader,Database,String,String,char,ImportFilter,boolean,boolean) * @see ImportUtil#importReader(BufferedReader,Database,String,String,char,ImportFilter,boolean,boolean)
*/ */
public String importReader(BufferedReader reader) throws IOException { public String importReader(BufferedReader reader) throws IOException {
return ImportUtil.importReader(reader, _db, _tableName, _delim, _quote,
return ImportUtil.importReader(reader, _db, _tableName, _delim, _quote,
_filter, _useExistingTable, _header); _filter, _useExistingTable, _header);
} }
} }

+ 8
- 7
src/test/java/com/healthmarketscience/jackcess/util/ImportTest.java View File

import junit.framework.TestCase; import junit.framework.TestCase;
import static com.healthmarketscience.jackcess.TestUtil.*; import static com.healthmarketscience.jackcess.TestUtil.*;


/**
/**
* @author Rob Di Marco * @author Rob Di Marco
*/
*/
public class ImportTest extends TestCase public class ImportTest extends TestCase
{ {


assertEquals(Arrays.asList( assertEquals(Arrays.asList(
"RESULT_PHYS_ID", "FIRST", "MIDDLE", "LAST", "OUTLIER", "RESULT_PHYS_ID", "FIRST", "MIDDLE", "LAST", "OUTLIER",
"RANK", "CLAIM_COUNT", "PROCEDURE_COUNT", "RANK", "CLAIM_COUNT", "PROCEDURE_COUNT",
"WEIGHTED_CLAIM_COUNT", "WEIGHTED_PROCEDURE_COUNT"),
"WEIGHTED_CLAIM_COUNT", "WEIGHTED_PROCEDURE_COUNT"),
colNames); colNames);


db.close(); db.close();
private List<Integer> _displaySizes = new ArrayList<Integer>(); private List<Integer> _displaySizes = new ArrayList<Integer>();
private List<Integer> _scales = new ArrayList<Integer>(); private List<Integer> _scales = new ArrayList<Integer>();
private List<Integer> _precisions = new ArrayList<Integer>(); private List<Integer> _precisions = new ArrayList<Integer>();
public Object invoke(Object proxy, Method method, Object[] args) public Object invoke(Object proxy, Method method, Object[] args)
{ {
String methodName = method.getName(); String methodName = method.getName();
return Boolean.FALSE; return Boolean.FALSE;
} else if(methodName.equals("getColumnCount")) { } else if(methodName.equals("getColumnCount")) {
return _types.size(); return _types.size();
} else if(methodName.equals("getColumnName")) {
} else if(methodName.equals("getColumnName") ||
methodName.equals("getColumnLabel")) {
return getValue(_names, args[0]); return getValue(_names, args[0]);
} else if(methodName.equals("getColumnDisplaySize")) { } else if(methodName.equals("getColumnDisplaySize")) {
return getValue(_displaySizes, args[0]); return getValue(_displaySizes, args[0]);
return values.get((Integer)index - 1); return values.get((Integer)index - 1);
} }
} }
}
}

Loading…
Cancel
Save