]> source.dussan.org Git - jackcess.git/commitdiff
allow column order in tables to be configured (fixes #3097387)
authorJames Ahlborn <jtahlborn@yahoo.com>
Wed, 3 Nov 2010 12:58:43 +0000 (12:58 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Wed, 3 Nov 2010 12:58:43 +0000 (12:58 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@497 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/java/com/healthmarketscience/jackcess/Column.java
src/java/com/healthmarketscience/jackcess/Database.java
src/java/com/healthmarketscience/jackcess/Table.java

index 4e6b33b724be1febccf17f4dca93d9580d125476..e5f4c95c01185e04cc18d7fe18f1e06c0099cd35 100644 (file)
@@ -20,6 +20,9 @@
         Implement some tweaks which allow jackcess to be used on the Android
         platform. (thanks to Miha Pirnat).
       </action>
+      <action dev="jahlborn" type="update" issue="3097387">
+        Allow column order in tables to be configured.
+      </action>
     </release>
     <release version="1.2.1" date="2010-08-01">
       <action dev="jahlborn" type="add" issue="3005272">
index 1eba8659dd4a347aff146951bd22ae393694de80..0593a4b77137a698619aeeb25d3822c5b6d21178 100644 (file)
@@ -145,6 +145,8 @@ public class Column implements Comparable<Column> {
   private short _columnNumber;
   /** index of the data for this column within a list of row data */
   private int _columnIndex;
+  /** display index of the data for this column */
+  private int _displayIndex;
   /** Column name */
   private String _name;
   /** the offset of the fixed data in the row */
@@ -178,10 +180,11 @@ public class Column implements Comparable<Column> {
    * @param buffer Buffer containing column definition
    * @param offset Offset in the buffer at which the column definition starts
    */
-  public Column(Table table, ByteBuffer buffer, int offset)
+  public Column(Table table, ByteBuffer buffer, int offset, int displayIndex)
     throws IOException
   {
     _table = table;
+    _displayIndex = displayIndex;
     if (LOG.isDebugEnabled()) {
       LOG.debug("Column def block:\n" + ByteUtil.toHexString(buffer, offset, 25));
     }
@@ -259,6 +262,10 @@ public class Column implements Comparable<Column> {
     _columnIndex = newColumnIndex;
   }
   
+  public int getDisplayIndex() {
+    return _displayIndex;
+  }
+
   /**
    * Also sets the length and the variable length flag, inferred from the
    * type.  For types with scale/precision, sets the scale and precision to
index 124fa706d8946cb887be5d6cfa9bcf3cfc4c046c..c15977bd557d4f091a6595dfac98c102212f59ca 100644 (file)
@@ -104,6 +104,10 @@ public class Database
   public static final String DEFAULT_RESOURCE_PATH = 
     "com/healthmarketscience/jackcess/";
 
+  /** the default sort order for table columns. */
+  public static final Table.ColumnOrder DEFAULT_COLUMN_ORDER = 
+    Table.ColumnOrder.DATA;
+
   /** (boolean) system property which can be used to disable the default big
       index support. */
   public static final String USE_BIG_INDEX_PROPERTY =
@@ -131,6 +135,12 @@ public class Database
   public static final String BROKEN_NIO_PROPERTY = 
     "com.healthmarketscience.jackcess.brokenNio";
 
+  /** system property which can be used to set the default sort order for
+      table columns.  Value should be one {@link Table.ColumnOrder} enum
+      values. */
+  public static final String COLUMN_ORDER_PROPERTY = 
+    "com.healthmarketscience.jackcess.columnOrder";
+
   /** default error handler used if none provided (just rethrows exception) */
   public static final ErrorHandler DEFAULT_ERROR_HANDLER = new ErrorHandler() {
       public Object handleRowError(Column column,
@@ -349,6 +359,8 @@ public class Database
   private Charset _charset;
   /** timezone to use when handling dates */
   private TimeZone _timeZone;
+  /** the ordering used for table columns */
+  private Table.ColumnOrder _columnOrder;
   
   /**
    * Open an existing Database.  If the existing file is not writeable, the
@@ -641,6 +653,7 @@ public class Database
 
       _format = JetFormat.getFormat(channel);
       _charset = ((charset == null) ? getDefaultCharset(_format) : charset);
+      _columnOrder = getDefaultColumnOrder();
       _fileFormat = fileFormat;
       _pageChannel = new PageChannel(channel, _format, autoSync);
       _timeZone = ((timeZone == null) ? getDefaultTimeZone() : timeZone);
@@ -759,6 +772,26 @@ public class Database
     _charset = newCharset;
   }
 
+  /**
+   * Gets currently configured {@link Table.ColumnOrder} (always non-{@code
+   * null}).
+   */
+  public Table.ColumnOrder getColumnOrder()
+  {
+    return _columnOrder;
+  }
+
+  /**
+   * Sets a new Table.ColumnOrder.  If {@code null}, resets to the value
+   * returned by {@link #getDefaultColumnOrder}.
+   */
+  public void setColumnOrder(Table.ColumnOrder newColumnOrder) {
+    if(newColumnOrder == null) {
+      newColumnOrder = getDefaultColumnOrder();
+    }
+    _columnOrder = newColumnOrder;
+  }
+
   /**
    * Returns the FileFormat of this database (which may involve inspecting the
    * database itself).
@@ -1561,6 +1594,25 @@ public class Database
     return format.CHARSET;
   }
   
+  /**
+   * Returns the default Table.ColumnOrder.  This defaults to
+   * {@link #DEFAULT_COLUMN_ORDER}, but can be overridden using the system
+   * property {@value #COLUMN_ORDER_PROPERTY}.
+   */
+  public static Table.ColumnOrder getDefaultColumnOrder()
+  {
+    String coProp = System.getProperty(COLUMN_ORDER_PROPERTY);
+    if(coProp != null) {
+      coProp = coProp.trim();
+      if(coProp.length() > 0) {
+        return Table.ColumnOrder.valueOf(coProp);
+      }
+    }
+
+    // use default order
+    return DEFAULT_COLUMN_ORDER;
+  }
+  
   /**
    * Copies the given InputStream to the given channel using the most
    * efficient means possible.
index 36f7c668665320f57dc1c4eae62e59f0b3ecb474..f6e754123b74e109038a6b098ec34bd6a38f9a91 100644 (file)
@@ -69,7 +69,17 @@ public class Table
   /** Table type code for user tables */
   public static final byte TYPE_USER = 0x4e;
 
-  /** comparator which sorts variable length columns vased on their index into
+  /** enum which controls the ordering of the columns in a table. */
+  public enum ColumnOrder {
+    /** columns are ordered based on the order of the data in the table (this
+        order does not change as columns are added to the table). */
+    DATA, 
+    /** columns are ordered based on the "display" order (this order can be
+        changed arbitrarily) */
+    DISPLAY;
+  }
+
+  /** comparator which sorts variable length columns based on their index into
       the variable length offset table */
   private static final Comparator<Column> VAR_LEN_COLUMN_COMPARATOR =
     new Comparator<Column>() {
@@ -80,6 +90,16 @@ public class Table
       }
     };
 
+  /** comparator which sorts columns based on their display index */
+  private static final Comparator<Column> DISPLAY_ORDER_COMPARATOR =
+    new Comparator<Column>() {
+      public int compare(Column c1, Column c2) {
+        return ((c1.getDisplayIndex() < c2.getDisplayIndex()) ? -1 :
+                ((c1.getDisplayIndex() > c2.getDisplayIndex()) ? 1 :
+                 0));
+      }
+    };
+
   /** owning database */
   private final Database _database;
   /** Type of the table (either TYPE_SYSTEM or TYPE_USER) */
@@ -1069,9 +1089,10 @@ public class Table
     
     int colOffset = getFormat().OFFSET_INDEX_DEF_BLOCK +
         _indexCount * getFormat().SIZE_INDEX_DEFINITION;
+    int dispIndex = 0;
     for (int i = 0; i < columnCount; i++) {
       Column column = new Column(this, tableBuffer,
-          colOffset + (i * getFormat().SIZE_COLUMN_HEADER));
+          colOffset + (i * getFormat().SIZE_COLUMN_HEADER), dispIndex++);
       _columns.add(column);
       if(column.isVariableLength()) {
         // also shove it in the variable columns list, which is ordered
@@ -1149,6 +1170,11 @@ public class Table
 
     // reset to end of index info
     tableBuffer.position(idxEndOffset);
+
+    // re-sort columns if necessary
+    if(getDatabase().getColumnOrder() != ColumnOrder.DATA) {
+      Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR);
+    }
   }
 
   /**