From c9a706c2346e9b75f953dfdbf001f1688e07f6d2 Mon Sep 17 00:00:00 2001 From: James Ahlborn Date: Fri, 8 Mar 2013 02:31:37 +0000 Subject: [PATCH] no longer use ColumnImpl to construct new tables; rip out some useless debug messages; enable filters to setup per-call state git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/jackcess-2@675 f203690c-595d-4dc9-a70b-905162fa7fd2 --- TODO.txt | 3 + .../jackcess/ColumnBuilder.java | 196 +++++++++++++++--- .../jackcess/ColumnImpl.java | 187 +++-------------- .../jackcess/DatabaseImpl.java | 4 +- .../jackcess/ExportFilter.java | 13 +- .../jackcess/ExportUtil.java | 3 + .../jackcess/ImportFilter.java | 14 +- .../jackcess/ImportUtil.java | 19 +- .../jackcess/IndexData.java | 2 +- .../jackcess/PageChannel.java | 3 - .../jackcess/PropertyMaps.java | 4 + .../jackcess/SimpleExportFilter.java | 4 + .../jackcess/SimpleImportFilter.java | 8 +- .../jackcess/TableBuilder.java | 13 +- .../jackcess/TableCreator.java | 24 ++- .../jackcess/TableImpl.java | 29 +-- .../jackcess/UsageMap.java | 4 - 17 files changed, 287 insertions(+), 243 deletions(-) diff --git a/TODO.txt b/TODO.txt index e630bde..9a89be1 100644 --- a/TODO.txt +++ b/TODO.txt @@ -35,3 +35,6 @@ Refactor goals: - remove debug log blocks - add Row interface - change savepoint to use table number instead of name? +- don't use columnimpl for creating tables + - clean up columnimpl/tableimpl constructors +- add updateCurrentRow(Map), add updateRow(Row) diff --git a/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java b/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java index 23154a1..a3212f2 100644 --- a/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java +++ b/src/java/com/healthmarketscience/jackcess/ColumnBuilder.java @@ -29,6 +29,9 @@ package com.healthmarketscience.jackcess; import java.sql.SQLException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + /** * Builder style class for constructing a Column. * @@ -36,20 +39,29 @@ import java.sql.SQLException; */ public class ColumnBuilder { + private static final Log LOG = LogFactory.getLog(ColumnBuilder.class); + /** name of the new column */ private String _name; /** the type of the new column */ private DataType _type; /** optional length for the new column */ - private Integer _length; + private Short _length; /** optional precision for the new column */ - private Integer _precision; + private Byte _precision; /** optional scale for the new column */ - private Integer _scale; + private Byte _scale; /** whether or not the column is auto-number */ private boolean _autoNumber; /** whether or not the column allows compressed unicode */ - private Boolean _compressedUnicode; + private boolean _compressedUnicode; + /** whether or not the column is a hyperlink (memo only) */ + private boolean _hyperlink; + /** 0-based column number */ + private short _columnNumber; + /** the collating sort order for a text field */ + private ColumnImpl.SortOrder _sortOrder; + public ColumnBuilder(String name) { this(name, null); @@ -60,6 +72,10 @@ public class ColumnBuilder { _type = type; } + public String getName() { + return _name; + } + /** * Sets the type for the new column. */ @@ -68,6 +84,10 @@ public class ColumnBuilder { return this; } + public DataType getType() { + return _type; + } + /** * Sets the type for the new column based on the given SQL type. */ @@ -89,26 +109,42 @@ public class ColumnBuilder { * Sets the precision for the new column. */ public ColumnBuilder setPrecision(int newPrecision) { - _precision = newPrecision; + _precision = (byte)newPrecision; return this; } + public byte getPrecision() { + return ((_precision != null) ? _precision : + (byte)(_type.getHasScalePrecision() ? _type.getDefaultPrecision() : 0)); + } + /** * Sets the scale for the new column. */ public ColumnBuilder setScale(int newScale) { - _scale = newScale; + _scale = (byte)newScale; return this; } + public byte getScale() { + return ((_scale != null) ? _scale : + (byte)(_type.getHasScalePrecision() ? _type.getDefaultScale() : 0)); + } + /** * Sets the length (in bytes) for the new column. */ public ColumnBuilder setLength(int length) { - _length = length; + _length = (short)length; return this; } + public short getLength() { + return ((_length != null) ? _length : + (short)(!_type.isVariableLength() ? _type.getFixedSize() : + (!_type.isLongValue() ? _type.getDefaultSize() : 0))); + } + /** * Sets the length (in type specific units) for the new column. */ @@ -131,6 +167,10 @@ public class ColumnBuilder { return this; } + public boolean isAutoNumber() { + return _autoNumber; + } + /** * Sets whether of not the new column allows unicode compression. */ @@ -139,10 +179,26 @@ public class ColumnBuilder { return this; } + public boolean isCompressedUnicode() { + return _compressedUnicode; + } + + /** + * Sets whether of not the new column allows unicode compression. + */ + public ColumnBuilder setHyperlink(boolean hyperlink) { + _hyperlink = hyperlink; + return this; + } + + public boolean isHyperlink() { + return _hyperlink; + } + /** * Sets all attributes except name from the given Column template. */ - public ColumnBuilder setFromColumn(ColumnImpl template) { + public ColumnBuilder setFromColumn(Column template) { DataType type = template.getType(); setType(type); setLength(template.getLength()); @@ -152,12 +208,31 @@ public class ColumnBuilder { setPrecision(template.getPrecision()); } setCompressedUnicode(template.isCompressedUnicode()); + setHyperlink(template.isHyperlink()); return this; } /** - * Escapes the new column's name using {@link Database#escapeIdentifier}. + * Sets all attributes except name from the given Column template. + */ + public ColumnBuilder setFromColumn(ColumnBuilder template) { + DataType type = template.getType(); + setType(type); + setLength(template.getLength()); + setAutoNumber(template.isAutoNumber()); + if(type.getHasScalePrecision()) { + setScale(template.getScale()); + setPrecision(template.getPrecision()); + } + setCompressedUnicode(template.isCompressedUnicode()); + setHyperlink(template.isHyperlink()); + + return this; + } + + /** + * Escapes the new column's name using {@link DatabaseImpl#escapeIdentifier}. */ public ColumnBuilder escapeName() { @@ -165,29 +240,100 @@ public class ColumnBuilder { return this; } + short getColumnNumber() { + return _columnNumber; + } + + void setColumnNumber(short newColumnNumber) { + _columnNumber = newColumnNumber; + } + + ColumnImpl.SortOrder getTextSortOrder() { + return _sortOrder; + } + + void setTextSortOrder(ColumnImpl.SortOrder newTextSortOrder) { + _sortOrder = newTextSortOrder; + } + /** - * Creates a new Column with the currently configured attributes. + * Checks that this column definition is valid. + * + * @throws IllegalArgumentException if this column definition is invalid. + * @usage _advanced_method_ */ - public ColumnImpl toColumn() { - ColumnImpl col = new ColumnImpl(); - col.setName(_name); - col.setType(_type); - if(_length != null) { - col.setLength(_length.shortValue()); + public void validate(JetFormat format) { + if(getType() == null) { + throw new IllegalArgumentException("must have type"); + } + DatabaseImpl.validateIdentifierName( + getName(), format.MAX_COLUMN_NAME_LENGTH, "column"); + + if(getType().isUnsupported()) { + throw new IllegalArgumentException( + "Cannot create column with unsupported type " + getType()); + } + if(!format.isSupportedDataType(getType())) { + throw new IllegalArgumentException( + "Database format " + format + " does not support type " + getType()); } - if(_precision != null) { - col.setPrecision(_precision.byteValue()); + + if(!getType().isVariableLength()) { + if(getLength() != getType().getFixedSize()) { + if(getLength() < getType().getFixedSize()) { + throw new IllegalArgumentException("invalid fixed length size"); + } + LOG.warn("Column length " + getLength() + + " longer than expected fixed size " + + getType().getFixedSize()); + } + } else if(!getType().isLongValue()) { + if(!getType().isValidSize(getLength())) { + throw new IllegalArgumentException("var length out of range"); + } + } + + if(getType().getHasScalePrecision()) { + if(!getType().isValidScale(getScale())) { + throw new IllegalArgumentException( + "Scale must be from " + getType().getMinScale() + " to " + + getType().getMaxScale() + " inclusive"); + } + if(!getType().isValidPrecision(getPrecision())) { + throw new IllegalArgumentException( + "Precision must be from " + getType().getMinPrecision() + " to " + + getType().getMaxPrecision() + " inclusive"); + } } - if(_scale != null) { - col.setScale(_scale.byteValue()); + + if(isAutoNumber()) { + if(!getType().mayBeAutoNumber()) { + throw new IllegalArgumentException( + "Auto number column must be long integer or guid"); + } } - if(_autoNumber) { - col.setAutoNumber(true); + + if(isCompressedUnicode()) { + if(!getType().isTextual()) { + throw new IllegalArgumentException( + "Only textual columns allow unicode compression (text/memo)"); + } } - if(_compressedUnicode != null) { - col.setCompressedUnicode(_compressedUnicode); + + if(isHyperlink()) { + if(getType() != DataType.MEMO) { + throw new IllegalArgumentException( + "Only memo columns can be hyperlinks"); + } } - return col; + } + + /** + * Creates a new Column with the currently configured attributes. + */ + public ColumnBuilder toColumn() { + // for backwards compat w/ old code + return this; } } diff --git a/src/java/com/healthmarketscience/jackcess/ColumnImpl.java b/src/java/com/healthmarketscience/jackcess/ColumnImpl.java index d6c7a74..796e5ad 100644 --- a/src/java/com/healthmarketscience/jackcess/ColumnImpl.java +++ b/src/java/com/healthmarketscience/jackcess/ColumnImpl.java @@ -203,27 +203,10 @@ public class ColumnImpl implements Column, Comparable { /** properties for this column, if any */ private PropertyMap _props; - /** - * @usage _general_method_ - */ - public ColumnImpl() { - this(null); - } - /** * @usage _advanced_method_ */ - public ColumnImpl(JetFormat format) { - _table = null; - } - - /** - * Only used by unit tests - */ - ColumnImpl(boolean testing, TableImpl table) { - if(!testing) { - throw new IllegalArgumentException(); - } + ColumnImpl(TableImpl table) { _table = table; } @@ -239,9 +222,6 @@ public class ColumnImpl implements Column, Comparable { { _table = table; _displayIndex = displayIndex; - if (LOG.isDebugEnabled()) { - LOG.debug("Column def block:\n" + ByteUtil.toHexString(buffer, offset, 25)); - } byte colType = buffer.get(offset + getFormat().OFFSET_COLUMN_TYPE); _columnNumber = buffer.getShort(offset + getFormat().OFFSET_COLUMN_NUMBER); @@ -424,20 +404,6 @@ public class ColumnImpl implements Column, Comparable { return _type.getSQLType(); } - /** - * @usage _general_method_ - */ - public void setSQLType(int type) throws SQLException { - setSQLType(type, 0); - } - - /** - * @usage _general_method_ - */ - public void setSQLType(int type, int lengthInUnits) throws SQLException { - setType(DataType.fromSQLType(type, lengthInUnits)); - } - public boolean isCompressedUnicode() { return _textInfo._compressedUnicode; } @@ -659,82 +625,6 @@ public class ColumnImpl implements Column, Comparable { } } - /** - * Checks that this column definition is valid. - * - * @throws IllegalArgumentException if this column definition is invalid. - * @usage _advanced_method_ - */ - public void validate(JetFormat format) { - if(getType() == null) { - throw new IllegalArgumentException("must have type"); - } - DatabaseImpl.validateIdentifierName(getName(), format.MAX_COLUMN_NAME_LENGTH, - "column"); - - if(getType().isUnsupported()) { - throw new IllegalArgumentException( - "Cannot create column with unsupported type " + getType()); - } - if(!format.isSupportedDataType(getType())) { - throw new IllegalArgumentException( - "Database format " + format + " does not support type " + getType()); - } - - if(isVariableLength() != getType().isVariableLength()) { - throw new IllegalArgumentException("invalid variable length setting"); - } - - if(!isVariableLength()) { - if(getLength() != getType().getFixedSize()) { - if(getLength() < getType().getFixedSize()) { - throw new IllegalArgumentException("invalid fixed length size"); - } - LOG.warn("Column length " + getLength() + - " longer than expected fixed size " + - getType().getFixedSize()); - } - } else if(!getType().isLongValue()) { - if(!getType().isValidSize(getLength())) { - throw new IllegalArgumentException("var length out of range"); - } - } - - if(getType().getHasScalePrecision()) { - if(!getType().isValidScale(getScale())) { - throw new IllegalArgumentException( - "Scale must be from " + getType().getMinScale() + " to " + - getType().getMaxScale() + " inclusive"); - } - if(!getType().isValidPrecision(getPrecision())) { - throw new IllegalArgumentException( - "Precision must be from " + getType().getMinPrecision() + " to " + - getType().getMaxPrecision() + " inclusive"); - } - } - - if(isAutoNumber()) { - if(!getType().mayBeAutoNumber()) { - throw new IllegalArgumentException( - "Auto number column must be long integer or guid"); - } - } - - if(isCompressedUnicode()) { - if(!getType().isTextual()) { - throw new IllegalArgumentException( - "Only textual columns allow unicode compression (text/memo)"); - } - } - - if(isHyperlink()) { - if(getType() != DataType.MEMO) { - throw new IllegalArgumentException( - "Only memo columns can be hyperlinks"); - } - } - } - public Object setRowValue(Object[] rowArray, Object value) { rowArray[_columnIndex] = value; return value; @@ -1694,15 +1584,27 @@ public class ColumnImpl implements Column, Comparable { /** * Constructs a byte containing the flags for this column. */ - private byte getColumnBitFlags() { + private static byte getColumnBitFlags(ColumnBuilder col) { byte flags = UNKNOWN_FLAG_MASK; - if(!isVariableLength()) { + if(!col.getType().isVariableLength()) { flags |= FIXED_LEN_FLAG_MASK; } - if(isAutoNumber()) { - flags |= getAutoNumberGenerator().getColumnFlags(); + if(col.isAutoNumber()) { + byte autoNumFlags = 0; + switch(col.getType()) { + case LONG: + case COMPLEX_TYPE: + autoNumFlags = AUTO_NUMBER_FLAG_MASK; + break; + case GUID: + autoNumFlags = AUTO_NUMBER_GUID_FLAG_MASK; + break; + default: + // unknown autonum type + } + flags |= autoNumFlags; } - if(isHyperlink()) { + if(col.isHyperlink()) { flags |= HYPERLINK_FLAG_MASK; } return flags; @@ -1791,10 +1693,10 @@ public class ColumnImpl implements Column, Comparable { * @return The number of variable length columns found in the list * @usage _advanced_method_ */ - public static short countVariableLength(List columns) { + public static short countVariableLength(List columns) { short rtn = 0; - for (ColumnImpl col : columns) { - if (col.isVariableLength()) { + for (ColumnBuilder col : columns) { + if (col.getType().isVariableLength()) { rtn++; } } @@ -1807,10 +1709,10 @@ public class ColumnImpl implements Column, Comparable { * found in the list * @usage _advanced_method_ */ - public static short countNonLongVariableLength(List columns) { + public static short countNonLongVariableLength(List columns) { short rtn = 0; - for (ColumnImpl col : columns) { - if (col.isVariableLength() && !col.getType().isLongValue()) { + for (ColumnBuilder col : columns) { + if (col.getType().isVariableLength() && !col.getType().isLongValue()) { rtn++; } } @@ -1978,7 +1880,7 @@ public class ColumnImpl implements Column, Comparable { protected static void writeDefinitions(TableCreator creator, ByteBuffer buffer) throws IOException { - List columns = creator.getColumns(); + List columns = creator.getColumns(); short columnNumber = (short) 0; short fixedOffset = (short) 0; short variableOffset = (short) 0; @@ -1986,7 +1888,7 @@ public class ColumnImpl implements Column, Comparable { // variable length values so that we have a better chance of fitting it // all (because "long variable" values can go in separate pages) short longVariableOffset = countNonLongVariableLength(columns); - for (ColumnImpl col : columns) { + for (ColumnBuilder col : columns) { // record this for later use when writing indexes col.setColumnNumber(columnNumber); @@ -1994,7 +1896,7 @@ public class ColumnImpl implements Column, Comparable { buffer.put(col.getType().getValue()); buffer.putInt(TableImpl.MAGIC_TABLE_NUMBER); //constant magic number buffer.putShort(columnNumber); //Column Number - if (col.isVariableLength()) { + if (col.getType().isVariableLength()) { if(!col.getType().isLongValue()) { buffer.putShort(variableOffset++); } else { @@ -2018,7 +1920,7 @@ public class ColumnImpl implements Column, Comparable { } buffer.putShort((short) 0); //Unknown } - buffer.put(col.getColumnBitFlags()); // misc col flags + buffer.put(getColumnBitFlags(col)); // misc col flags if (col.isCompressedUnicode()) { //Compressed buffer.put((byte) 1); } else { @@ -2026,7 +1928,7 @@ public class ColumnImpl implements Column, Comparable { } buffer.putInt(0); //Unknown, but always 0. //Offset for fixed length columns - if (col.isVariableLength()) { + if (col.getType().isVariableLength()) { buffer.putShort((short) 0); } else { buffer.putShort(fixedOffset); @@ -2038,12 +1940,8 @@ public class ColumnImpl implements Column, Comparable { buffer.putShort((short)0x0000); // unused } columnNumber++; - if (LOG.isDebugEnabled()) { - LOG.debug("Creating new column def block\n" + ByteUtil.toHexString( - buffer, position, creator.getFormat().SIZE_COLUMN_DEF_BLOCK)); - } } - for (ColumnImpl col : columns) { + for (ColumnBuilder col : columns) { TableImpl.writeName(buffer, col.getName(), creator.getCharset()); } } @@ -2169,11 +2067,6 @@ public class ColumnImpl implements Column, Comparable { */ public abstract Object getNext(Object prevRowValue); - /** - * Returns the flags used when writing this column. - */ - public abstract int getColumnFlags(); - /** * Returns the type of values generated by this generator. */ @@ -2196,11 +2089,6 @@ public class ColumnImpl implements Column, Comparable { return getTable().getNextLongAutoNumber(); } - @Override - public int getColumnFlags() { - return AUTO_NUMBER_FLAG_MASK; - } - @Override public DataType getType() { return DataType.LONG; @@ -2225,11 +2113,6 @@ public class ColumnImpl implements Column, Comparable { return _lastAutoNumber; } - @Override - public int getColumnFlags() { - return AUTO_NUMBER_GUID_FLAG_MASK; - } - @Override public DataType getType() { return DataType.GUID; @@ -2257,11 +2140,6 @@ public class ColumnImpl implements Column, Comparable { return new ComplexValueForeignKey(ColumnImpl.this, nextComplexAutoNum); } - @Override - public int getColumnFlags() { - return AUTO_NUMBER_FLAG_MASK; - } - @Override public DataType getType() { return DataType.COMPLEX_TYPE; @@ -2286,11 +2164,6 @@ public class ColumnImpl implements Column, Comparable { throw new UnsupportedOperationException(); } - @Override - public int getColumnFlags() { - throw new UnsupportedOperationException(); - } - @Override public DataType getType() { return _genType; diff --git a/src/java/com/healthmarketscience/jackcess/DatabaseImpl.java b/src/java/com/healthmarketscience/jackcess/DatabaseImpl.java index 30f61db..43cf0ee 100644 --- a/src/java/com/healthmarketscience/jackcess/DatabaseImpl.java +++ b/src/java/com/healthmarketscience/jackcess/DatabaseImpl.java @@ -934,7 +934,7 @@ public class DatabaseImpl implements Database * @param columns List of Columns in the table * @usage _general_method_ */ - public void createTable(String name, List columns) + public void createTable(String name, List columns) throws IOException { createTable(name, columns, null); @@ -947,7 +947,7 @@ public class DatabaseImpl implements Database * @param indexes List of IndexBuilders describing indexes for the table * @usage _general_method_ */ - public void createTable(String name, List columns, + public void createTable(String name, List columns, List indexes) throws IOException { diff --git a/src/java/com/healthmarketscience/jackcess/ExportFilter.java b/src/java/com/healthmarketscience/jackcess/ExportFilter.java index 19faed1..47cc3bb 100644 --- a/src/java/com/healthmarketscience/jackcess/ExportFilter.java +++ b/src/java/com/healthmarketscience/jackcess/ExportFilter.java @@ -38,6 +38,16 @@ import java.util.List; */ public interface ExportFilter { + /** + * Called before any calls {@link #filterColumns} and {@link #filterRow} for + * a single export operation. Allows the given instance to return a + * per-call instance which can maintain state. + * + * @return the ExportFilter instance to use for the rest of the export + * operation + */ + public ExportFilter init(); + /** * The columns that should be used to create the exported file. * @@ -46,7 +56,8 @@ public interface ExportFilter { * modified and returned * @return the columns to use when creating the export file */ - public List filterColumns(List columns) throws IOException; + public List filterColumns(List columns) + throws IOException; /** * The desired values for the row. diff --git a/src/java/com/healthmarketscience/jackcess/ExportUtil.java b/src/java/com/healthmarketscience/jackcess/ExportUtil.java index 5b37c70..69647fa 100644 --- a/src/java/com/healthmarketscience/jackcess/ExportUtil.java +++ b/src/java/com/healthmarketscience/jackcess/ExportUtil.java @@ -303,6 +303,9 @@ public class ExportUtil { "(?:" + Pattern.quote(delimiter) + ")|(?:" + Pattern.quote("" + quote) + ")|(?:[\n\r])"); + // allow filter to setup per-call state + filter = filter.init(); + List origCols = cursor.getTable().getColumns(); List columns = new ArrayList(origCols); columns = filter.filterColumns(columns); diff --git a/src/java/com/healthmarketscience/jackcess/ImportFilter.java b/src/java/com/healthmarketscience/jackcess/ImportFilter.java index ca12b42..82f27d3 100644 --- a/src/java/com/healthmarketscience/jackcess/ImportFilter.java +++ b/src/java/com/healthmarketscience/jackcess/ImportFilter.java @@ -40,6 +40,16 @@ import java.util.List; */ public interface ImportFilter { + /** + * Called before any calls {@link #filterColumns} and {@link #filterRow} for + * a single import operation. Allows the given instance to return a + * per-call instance which can maintain state. + * + * @return the ImportFilter instance to use for the rest of the import + * operation + */ + public ImportFilter init(); + /** * The columns that should be used to create the imported table. * @param destColumns the columns as determined by the import code, may be @@ -48,8 +58,8 @@ public interface ImportFilter { * JDBC source * @return the columns to use when creating the import table */ - public List filterColumns(List destColumns, - ResultSetMetaData srcColumns) + public List filterColumns(List destColumns, + ResultSetMetaData srcColumns) throws SQLException, IOException; /** diff --git a/src/java/com/healthmarketscience/jackcess/ImportUtil.java b/src/java/com/healthmarketscience/jackcess/ImportUtil.java index da2b502..be41678 100644 --- a/src/java/com/healthmarketscience/jackcess/ImportUtil.java +++ b/src/java/com/healthmarketscience/jackcess/ImportUtil.java @@ -68,13 +68,12 @@ public class ImportUtil * * @return a List of Columns */ - public static List toColumns(ResultSetMetaData md) + public static List toColumns(ResultSetMetaData md) throws SQLException { - List columns = new LinkedList(); + List columns = new LinkedList(); for (int i = 1; i <= md.getColumnCount(); i++) { - ColumnImpl column = new ColumnImpl(); - column.setName(DatabaseImpl.escapeIdentifier(md.getColumnName(i))); + ColumnBuilder column = new ColumnBuilder(md.getColumnName(i)).escapeName(); int lengthInUnits = md.getColumnDisplaySize(i); column.setSQLType(md.getColumnType(i), lengthInUnits); DataType type = column.getType(); @@ -164,10 +163,13 @@ public class ImportUtil { ResultSetMetaData md = source.getMetaData(); + // allow filter to setup per-call state + filter = filter.init(); + name = DatabaseImpl.escapeIdentifier(name); Table table = null; if(!useExistingTable || ((table = db.getTable(name)) == null)) { - List columns = toColumns(md); + List columns = toColumns(md); table = createUniqueTable(db, name, columns, md, filter); } @@ -452,12 +454,15 @@ public class ImportUtil Pattern delimPat = Pattern.compile(delim); + // allow filter to setup per-call state + filter = filter.init(); + try { name = DatabaseImpl.escapeIdentifier(name); Table table = null; if(!useExistingTable || ((table = db.getTable(name)) == null)) { - List columns = new LinkedList(); + List columns = new LinkedList(); Object[] columnNames = splitLine(line, delimPat, quote, in, 0); for (int i = 0; i < columnNames.length; i++) { @@ -591,7 +596,7 @@ public class ImportUtil * Returns a new table with a unique name and the given table definition. */ private static Table createUniqueTable(DatabaseImpl db, String name, - List columns, + List columns, ResultSetMetaData md, ImportFilter filter) throws IOException, SQLException diff --git a/src/java/com/healthmarketscience/jackcess/IndexData.java b/src/java/com/healthmarketscience/jackcess/IndexData.java index b2be17d..64ec4b3 100644 --- a/src/java/com/healthmarketscience/jackcess/IndexData.java +++ b/src/java/com/healthmarketscience/jackcess/IndexData.java @@ -483,7 +483,7 @@ public class IndexData { flags = idxCol.getFlags(); // find actual table column number - for(ColumnImpl col : creator.getColumns()) { + for(ColumnBuilder col : creator.getColumns()) { if(col.getName().equalsIgnoreCase(idxCol.getName())) { columnNumber = col.getColumnNumber(); break; diff --git a/src/java/com/healthmarketscience/jackcess/PageChannel.java b/src/java/com/healthmarketscience/jackcess/PageChannel.java index fb02d1f..8df74d7 100644 --- a/src/java/com/healthmarketscience/jackcess/PageChannel.java +++ b/src/java/com/healthmarketscience/jackcess/PageChannel.java @@ -166,9 +166,6 @@ public class PageChannel implements Channel, Flushable { throws IOException { validatePageNumber(pageNumber); - if (LOG.isDebugEnabled()) { - LOG.debug("Reading in page " + Integer.toHexString(pageNumber)); - } buffer.clear(); int bytesRead = _channel.read( buffer, (long) pageNumber * (long) getFormat().PAGE_SIZE); diff --git a/src/java/com/healthmarketscience/jackcess/PropertyMaps.java b/src/java/com/healthmarketscience/jackcess/PropertyMaps.java index 2371841..1932dd6 100644 --- a/src/java/com/healthmarketscience/jackcess/PropertyMaps.java +++ b/src/java/com/healthmarketscience/jackcess/PropertyMaps.java @@ -304,6 +304,10 @@ public class PropertyMaps implements Iterable */ private class PropColumn extends ColumnImpl { + private PropColumn() { + super(null); + } + @Override public DatabaseImpl getDatabase() { return _database; diff --git a/src/java/com/healthmarketscience/jackcess/SimpleExportFilter.java b/src/java/com/healthmarketscience/jackcess/SimpleExportFilter.java index 17d0528..ad04eef 100644 --- a/src/java/com/healthmarketscience/jackcess/SimpleExportFilter.java +++ b/src/java/com/healthmarketscience/jackcess/SimpleExportFilter.java @@ -43,6 +43,10 @@ public class SimpleExportFilter implements ExportFilter { public SimpleExportFilter() { } + public ExportFilter init() { + return this; + } + public List filterColumns(List columns) throws IOException { return columns; } diff --git a/src/java/com/healthmarketscience/jackcess/SimpleImportFilter.java b/src/java/com/healthmarketscience/jackcess/SimpleImportFilter.java index 38387ca..de1fcfc 100644 --- a/src/java/com/healthmarketscience/jackcess/SimpleImportFilter.java +++ b/src/java/com/healthmarketscience/jackcess/SimpleImportFilter.java @@ -44,9 +44,13 @@ public class SimpleImportFilter implements ImportFilter { public SimpleImportFilter() { } + + public ImportFilter init() { + return this; + } - public List filterColumns(List destColumns, - ResultSetMetaData srcColumns) + public List filterColumns(List destColumns, + ResultSetMetaData srcColumns) throws SQLException, IOException { return destColumns; diff --git a/src/java/com/healthmarketscience/jackcess/TableBuilder.java b/src/java/com/healthmarketscience/jackcess/TableBuilder.java index 09b3876..6ef3f5a 100644 --- a/src/java/com/healthmarketscience/jackcess/TableBuilder.java +++ b/src/java/com/healthmarketscience/jackcess/TableBuilder.java @@ -41,7 +41,7 @@ public class TableBuilder { /** name of the new table */ private String _name; /** columns for the new table */ - private List _columns = new ArrayList(); + private List _columns = new ArrayList(); /** indexes for the new table */ private List _indexes = new ArrayList(); /** whether or not table/column/index names are automatically escaped */ @@ -64,21 +64,14 @@ public class TableBuilder { /** * Adds a Column to the new table. */ - public TableBuilder addColumn(ColumnImpl column) { + public TableBuilder addColumn(ColumnBuilder column) { if(_escapeIdentifiers) { - column.setName(DatabaseImpl.escapeIdentifier(column.getName())); + column.escapeName(); } _columns.add(column); return this; } - /** - * Adds a Column to the new table. - */ - public TableBuilder addColumn(ColumnBuilder columnBuilder) { - return addColumn(columnBuilder.toColumn()); - } - /** * Adds an IndexBuilder to the new table. */ diff --git a/src/java/com/healthmarketscience/jackcess/TableCreator.java b/src/java/com/healthmarketscience/jackcess/TableCreator.java index bbe2df9..dfceab9 100644 --- a/src/java/com/healthmarketscience/jackcess/TableCreator.java +++ b/src/java/com/healthmarketscience/jackcess/TableCreator.java @@ -21,6 +21,7 @@ package com.healthmarketscience.jackcess; import java.io.IOException; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -39,7 +40,7 @@ class TableCreator { private final DatabaseImpl _database; private final String _name; - private final List _columns; + private final List _columns; private final List _indexes; private final Map _indexStates = new HashMap(); @@ -48,7 +49,7 @@ class TableCreator private int _indexCount; private int _logicalIndexCount; - public TableCreator(DatabaseImpl database, String name, List columns, + public TableCreator(DatabaseImpl database, String name, List columns, List indexes) { _database = database; _name = name; @@ -77,7 +78,7 @@ class TableCreator return _umapPageNumber; } - public List getColumns() { + public List getColumns() { return _columns; } @@ -162,7 +163,7 @@ class TableCreator Set colNames = new HashSet(); // next, validate the column definitions - for(ColumnImpl column : _columns) { + for(ColumnBuilder column : _columns) { // FIXME for now, we can't create complex columns if(column.getType() == DataType.COMPLEX_TYPE) { @@ -182,11 +183,11 @@ class TableCreator } } - List autoCols = TableImpl.getAutoNumberColumns(_columns); + List autoCols = getAutoNumberColumns(); if(autoCols.size() > 1) { // for most autonumber types, we can only have one of each type Set autoTypes = EnumSet.noneOf(DataType.class); - for(ColumnImpl c : autoCols) { + for(ColumnBuilder c : autoCols) { if(!c.getType().isMultipleAutoNumberAllowed() && !autoTypes.add(c.getType())) { throw new IllegalArgumentException( @@ -217,6 +218,17 @@ class TableCreator } } + private List getAutoNumberColumns() + { + List autoCols = new ArrayList(1); + for(ColumnBuilder c : _columns) { + if(c.isAutoNumber()) { + autoCols.add(c); + } + } + return autoCols; + } + /** * Maintains additional state used during index creation. * @usage _advanced_class_ diff --git a/src/java/com/healthmarketscience/jackcess/TableImpl.java b/src/java/com/healthmarketscience/jackcess/TableImpl.java index a4e21a4..5c5df28 100644 --- a/src/java/com/healthmarketscience/jackcess/TableImpl.java +++ b/src/java/com/healthmarketscience/jackcess/TableImpl.java @@ -103,7 +103,7 @@ public class TableImpl implements Table /** owning database */ private final DatabaseImpl _database; /** additional table flags from the catalog entry */ - private int _flags; + private final int _flags; /** Type of the table (either TYPE_SYSTEM or TYPE_USER) */ private byte _tableType; /** Number of actual indexes on the table */ @@ -123,7 +123,7 @@ public class TableImpl implements Table /** max Number of variable columns in the table */ private short _maxVarColumnCount; /** List of columns in this table, ordered by column number */ - private List _columns = new ArrayList(); + private final List _columns = new ArrayList(); /** List of variable length columns in this table, ordered by offset */ private final List _varColumns = new ArrayList(); /** List of autonumber columns in this table, ordered by column number */ @@ -186,6 +186,7 @@ public class TableImpl implements Table _name = null; setColumns(columns); _fkEnforcer = null; + _flags = 0; } /** @@ -313,7 +314,7 @@ public class TableImpl implements Table * Only called by unit tests */ private void setColumns(List columns) { - _columns = columns; + _columns.addAll(columns); int colIdx = 0; int varLenIdx = 0; int fixedOffset = 0; @@ -897,7 +898,7 @@ public class TableImpl implements Table // total up the amount of space used by the column and index names (2 // bytes per char + 2 bytes for the length) - for(ColumnImpl col : creator.getColumns()) { + for(ColumnBuilder col : creator.getColumns()) { int nameByteLen = (col.getName().length() * JetFormat.TEXT_FIELD_UNIT_SIZE); totalTableDefSize += nameByteLen + 2; @@ -998,7 +999,7 @@ public class TableImpl implements Table TableCreator creator, ByteBuffer buffer, int totalTableDefSize) throws IOException { - List columns = creator.getColumns(); + List columns = creator.getColumns(); //Start writing the tdef writeTablePageHeader(buffer); @@ -1020,13 +1021,6 @@ public class TableImpl implements Table ByteUtil.put3ByteInt(buffer, creator.getUmapPageNumber()); //Usage map page number buffer.put((byte) 1); //Free map row number ByteUtil.put3ByteInt(buffer, creator.getUmapPageNumber()); //Free map page number - if (LOG.isDebugEnabled()) { - int position = buffer.position(); - buffer.rewind(); - LOG.debug("Creating new table def block:\n" + ByteUtil.toHexString( - buffer, creator.getFormat().SIZE_TDEF_HEADER)); - buffer.position(position); - } } /** @@ -1158,11 +1152,6 @@ public class TableImpl implements Table */ private void readTableDefinition(ByteBuffer tableBuffer) throws IOException { - if (LOG.isDebugEnabled()) { - tableBuffer.rewind(); - LOG.debug("Table def block:\n" + ByteUtil.toHexString(tableBuffer, - getFormat().SIZE_TDEF_HEADER)); - } _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS); _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER); if(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) { @@ -1638,9 +1627,6 @@ public class TableImpl implements Table * @return Page number of the new page */ private ByteBuffer newDataPage() throws IOException { - if (LOG.isDebugEnabled()) { - LOG.debug("Creating new data page"); - } ByteBuffer dataPage = _addRowBufferH.setNewPage(getPageChannel()); dataPage.put(PageTypes.DATA); //Page type dataPage.put((byte) 1); //Unknown @@ -1810,9 +1796,6 @@ public class TableImpl implements Table nullMask.write(buffer); //Null mask buffer.flip(); - if (LOG.isDebugEnabled()) { - LOG.debug("Creating new data block:\n" + ByteUtil.toHexString(buffer, buffer.limit())); - } return buffer; } diff --git a/src/java/com/healthmarketscience/jackcess/UsageMap.java b/src/java/com/healthmarketscience/jackcess/UsageMap.java index 6e3b560..5514afa 100644 --- a/src/java/com/healthmarketscience/jackcess/UsageMap.java +++ b/src/java/com/healthmarketscience/jackcess/UsageMap.java @@ -92,10 +92,6 @@ public class UsageMap _rowStart = rowStart; _tableBuffer.position(_rowStart + getFormat().OFFSET_USAGE_MAP_START); _startOffset = _tableBuffer.position(); - if (LOG.isDebugEnabled()) { - LOG.debug("Usage map block:\n" + ByteUtil.toHexString(_tableBuffer, _rowStart, - tableBuffer.limit() - _rowStart)); - } } public DatabaseImpl getDatabase() { -- 2.39.5