]> source.dussan.org Git - jackcess.git/commitdiff
no longer use ColumnImpl to construct new tables; rip out some useless debug messages...
authorJames Ahlborn <jtahlborn@yahoo.com>
Fri, 8 Mar 2013 02:31:37 +0000 (02:31 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Fri, 8 Mar 2013 02:31:37 +0000 (02:31 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/jackcess-2@675 f203690c-595d-4dc9-a70b-905162fa7fd2

17 files changed:
TODO.txt
src/java/com/healthmarketscience/jackcess/ColumnBuilder.java
src/java/com/healthmarketscience/jackcess/ColumnImpl.java
src/java/com/healthmarketscience/jackcess/DatabaseImpl.java
src/java/com/healthmarketscience/jackcess/ExportFilter.java
src/java/com/healthmarketscience/jackcess/ExportUtil.java
src/java/com/healthmarketscience/jackcess/ImportFilter.java
src/java/com/healthmarketscience/jackcess/ImportUtil.java
src/java/com/healthmarketscience/jackcess/IndexData.java
src/java/com/healthmarketscience/jackcess/PageChannel.java
src/java/com/healthmarketscience/jackcess/PropertyMaps.java
src/java/com/healthmarketscience/jackcess/SimpleExportFilter.java
src/java/com/healthmarketscience/jackcess/SimpleImportFilter.java
src/java/com/healthmarketscience/jackcess/TableBuilder.java
src/java/com/healthmarketscience/jackcess/TableCreator.java
src/java/com/healthmarketscience/jackcess/TableImpl.java
src/java/com/healthmarketscience/jackcess/UsageMap.java

index e630bdedad08ebd2cfd2b001e55c6760e829fb36..9a89be19036b8b40ecc3995df879c93c3885cf98 100644 (file)
--- 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)
index 23154a168edc59510892c63e3c1d1375eab6da38..a3212f29b6067cb431173b019884659aa2f5906f 100644 (file)
@@ -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;
   }
   
 }
index d6c7a748c3cff28ab15d20a602f76a4c5615d24f..796e5ad5d00aeb3bc8f793ae7d024304d06bc8a1 100644 (file)
@@ -203,27 +203,10 @@ public class ColumnImpl implements Column, Comparable<ColumnImpl> {
   /** 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<ColumnImpl> {
   {
     _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<ColumnImpl> {
     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<ColumnImpl> {
     }
   }
   
-  /**
-   * 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<ColumnImpl> {
   /**
    * 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<ColumnImpl> {
    * @return The number of variable length columns found in the list
    * @usage _advanced_method_
    */
-  public static short countVariableLength(List<ColumnImpl> columns) {
+  public static short countVariableLength(List<ColumnBuilder> 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<ColumnImpl> {
    *         found in the list
    * @usage _advanced_method_
    */
-  public static short countNonLongVariableLength(List<ColumnImpl> columns) {
+  public static short countNonLongVariableLength(List<ColumnBuilder> 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<ColumnImpl> {
   protected static void writeDefinitions(TableCreator creator, ByteBuffer buffer)
     throws IOException
   {
-    List<ColumnImpl> columns = creator.getColumns();
+    List<ColumnBuilder> 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<ColumnImpl> {
     // 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<ColumnImpl> {
       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<ColumnImpl> {
         }
         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<ColumnImpl> {
       }
       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<ColumnImpl> {
         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<ColumnImpl> {
      */
     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<ColumnImpl> {
       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<ColumnImpl> {
       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<ColumnImpl> {
       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<ColumnImpl> {
       throw new UnsupportedOperationException();
     }
 
-    @Override
-    public int getColumnFlags() {
-      throw new UnsupportedOperationException();
-    }
-
     @Override
     public DataType getType() {
       return _genType;
index 30f61db683b982a23b268160081a473a4820b5f2..43cf0ee0e7ac69ac660db31cd154b8a6913f94b8 100644 (file)
@@ -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<ColumnImpl> columns)
+  public void createTable(String name, List<ColumnBuilder> 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<ColumnImpl> columns,
+  public void createTable(String name, List<ColumnBuilder> columns,
                           List<IndexBuilder> indexes)
     throws IOException
   {
index 19faed1e729ec0c6187c4442660dbf01dff52368..47cc3bb026648b3e23a82e9662425777e6c8d19e 100644 (file)
@@ -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<ColumnImpl> filterColumns(List<ColumnImpl> columns) throws IOException;
+  public List<ColumnImpl> filterColumns(List<ColumnImpl> columns) 
+    throws IOException;
 
   /**
    * The desired values for the row.
index 5b37c70d660bf7305a50e5c9bef0c63173086aa8..69647faa273cf5a6491d76ca9e040d115b15ede1 100644 (file)
@@ -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<ColumnImpl> origCols = cursor.getTable().getColumns();
     List<ColumnImpl> columns = new ArrayList<ColumnImpl>(origCols);
     columns = filter.filterColumns(columns);
index ca12b42de3abadf7f3827e0184f083f3c711e607..82f27d3e3154d3ca0a027a86ada390389400c1a7 100644 (file)
@@ -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<ColumnImpl> filterColumns(List<ColumnImpl> destColumns,
-                                    ResultSetMetaData srcColumns)
+  public List<ColumnBuilder> filterColumns(List<ColumnBuilder> destColumns,
+                                           ResultSetMetaData srcColumns)
      throws SQLException, IOException;
 
   /**
index da2b5021b207cf8864e1686ec74e79718b087a0b..be4167815dca2890e1f57b7bf869de83db0fc186 100644 (file)
@@ -68,13 +68,12 @@ public class ImportUtil
    *
    * @return a List of Columns
    */
-  public static List<ColumnImpl> toColumns(ResultSetMetaData md)
+  public static List<ColumnBuilder> toColumns(ResultSetMetaData md)
     throws SQLException
   {
-      List<ColumnImpl> columns = new LinkedList<ColumnImpl>();
+      List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
       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<ColumnImpl> columns = toColumns(md);
+      List<ColumnBuilder> 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<ColumnImpl> columns = new LinkedList<ColumnImpl>();
+        List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
         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<ColumnImpl> columns,
+                                         List<ColumnBuilder> columns,
                                          ResultSetMetaData md, 
                                          ImportFilter filter)
     throws IOException, SQLException
index b2be17dfedb7e2a511e854e4cae5670bd3363034..64ec4b343a1f2d54bb5789929a299b923616a185 100644 (file)
@@ -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;
index fb02d1fff219a48bece87409a18276a49c0aab51..8df74d784e372fbeb6e7c42803bf255c59dd37fe 100644 (file)
@@ -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);
index 2371841afc70fe82e0573510269ee2745968532f..1932dd658a43e8c72978528c082f9407d376f29f 100644 (file)
@@ -304,6 +304,10 @@ public class PropertyMaps implements Iterable<PropertyMap>
      */
     private class PropColumn extends ColumnImpl
     {
+      private PropColumn() {
+        super(null);
+      }
+      
       @Override
       public DatabaseImpl getDatabase() {
         return _database;
index 17d052820c455e5f31ec0903c013270789bbd6b1..ad04eefd3fb184e598be9d9699238465b91d8192 100644 (file)
@@ -43,6 +43,10 @@ public class SimpleExportFilter implements ExportFilter {
   public SimpleExportFilter() {
   }
 
+  public ExportFilter init() {
+    return this;
+  }
+
   public List<ColumnImpl> filterColumns(List<ColumnImpl> columns) throws IOException {
     return columns;
   }
index 38387ca1e0d468000e9ad8bbe935c726bc055678..de1fcfc93d1b92e7c703cf6dbdd2e2108e0ddd77 100644 (file)
@@ -44,9 +44,13 @@ public class SimpleImportFilter implements ImportFilter {
   
   public SimpleImportFilter() {
   }
+
+  public ImportFilter init() {
+    return this;
+  }
   
-  public List<ColumnImpl> filterColumns(List<ColumnImpl> destColumns,
-                                    ResultSetMetaData srcColumns)
+  public List<ColumnBuilder> filterColumns(List<ColumnBuilder> destColumns,
+                                           ResultSetMetaData srcColumns)
      throws SQLException, IOException
   {
     return destColumns;
index 09b38766e3f699742d225272ed01558b0a391c8f..6ef3f5acc0ed1bc9bbfdf90e21bed91fe3af7d91 100644 (file)
@@ -41,7 +41,7 @@ public class TableBuilder {
   /** name of the new table */
   private String _name;
   /** columns for the new table */
-  private List<ColumnImpl> _columns = new ArrayList<ColumnImpl>();
+  private List<ColumnBuilder> _columns = new ArrayList<ColumnBuilder>();
   /** indexes for the new table */
   private List<IndexBuilder> _indexes = new ArrayList<IndexBuilder>();
   /** 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.
    */
index bbe2df925c0ba2769f3846f7e3105f20ba0ef097..dfceab9f179533aee2dc96429b8bd2d784738817 100644 (file)
@@ -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<ColumnImpl> _columns;
+  private final List<ColumnBuilder> _columns;
   private final List<IndexBuilder> _indexes;
   private final Map<IndexBuilder,IndexState> _indexStates = 
     new HashMap<IndexBuilder,IndexState>();
@@ -48,7 +49,7 @@ class TableCreator
   private int _indexCount;
   private int _logicalIndexCount;
 
-  public TableCreator(DatabaseImpl database, String name, List<ColumnImpl> columns,
+  public TableCreator(DatabaseImpl database, String name, List<ColumnBuilder> columns,
                       List<IndexBuilder> indexes) {
     _database = database;
     _name = name;
@@ -77,7 +78,7 @@ class TableCreator
     return _umapPageNumber;
   }
 
-  public List<ColumnImpl> getColumns() {
+  public List<ColumnBuilder> getColumns() {
     return _columns;
   }
 
@@ -162,7 +163,7 @@ class TableCreator
 
     Set<String> colNames = new HashSet<String>();
     // 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<ColumnImpl> autoCols = TableImpl.getAutoNumberColumns(_columns);
+    List<ColumnBuilder> autoCols = getAutoNumberColumns();
     if(autoCols.size() > 1) {
       // for most autonumber types, we can only have one of each type
       Set<DataType> 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<ColumnBuilder> getAutoNumberColumns() 
+  {
+    List<ColumnBuilder> autoCols = new ArrayList<ColumnBuilder>(1);
+    for(ColumnBuilder c : _columns) {
+      if(c.isAutoNumber()) {
+        autoCols.add(c);
+      }
+    }
+    return autoCols;
+  }
+
   /**
    * Maintains additional state used during index creation.
    * @usage _advanced_class_
index a4e21a436a426a2be329f29a5adc1be468c10d51..5c5df283f4d619b5e9e35d4c4aeccd1f7f39d185 100644 (file)
@@ -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<ColumnImpl> _columns = new ArrayList<ColumnImpl>();
+  private final List<ColumnImpl> _columns = new ArrayList<ColumnImpl>();
   /** List of variable length columns in this table, ordered by offset */
   private final List<ColumnImpl> _varColumns = new ArrayList<ColumnImpl>();
   /** 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<ColumnImpl> 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<ColumnImpl> columns = creator.getColumns();
+    List<ColumnBuilder> 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;
   }
 
index 6e3b560d4c564707a967f3dfc7ad4495f0fe673e..5514afa3c0072df2dfc1014c1b2f87b3db30f988 100644 (file)
@@ -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() {