View Javadoc
1   /*
2   Copyright (c) 2011 James Ahlborn
3   
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7   
8       http://www.apache.org/licenses/LICENSE-2.0
9   
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15  */
16  
17  package com.healthmarketscience.jackcess.impl.complex;
18  
19  import java.io.IOException;
20  import java.util.Collections;
21  import java.util.Date;
22  import java.util.List;
23  
24  import com.healthmarketscience.jackcess.Column;
25  import com.healthmarketscience.jackcess.Row;
26  import com.healthmarketscience.jackcess.Table;
27  import com.healthmarketscience.jackcess.complex.ComplexDataType;
28  import com.healthmarketscience.jackcess.complex.ComplexValue;
29  import com.healthmarketscience.jackcess.complex.ComplexValueForeignKey;
30  import com.healthmarketscience.jackcess.complex.Version;
31  import com.healthmarketscience.jackcess.complex.VersionHistoryColumnInfo;
32  import com.healthmarketscience.jackcess.impl.ColumnImpl;
33  
34  /**
35   * Complex column info for a column which tracking the version history of an
36   * "append only" memo column.
37   * <p>
38   * Note, the strongly typed update/delete methods are <i>not</i> supported for
39   * version history columns (the data is supposed to be immutable).  That said,
40   * the "raw" update/delete methods are supported for those that <i>really</i>
41   * want to muck with the version history data.
42   *
43   * @author James Ahlborn
44   */
45  public class VersionHistoryColumnInfoImpl extends ComplexColumnInfoImpl<Version> 
46    implements VersionHistoryColumnInfo
47  {
48    private final Column _valueCol;
49    private final Column _modifiedCol;
50    
51    public VersionHistoryColumnInfoImpl(Column column, int complexId,
52                                        Table typeObjTable, Table flatTable) 
53      throws IOException
54    {
55      super(column, complexId, typeObjTable, flatTable);
56  
57      Column valueCol = null;
58      Column modifiedCol = null;
59      for(Column col : getTypeColumns()) {
60        switch(col.getType()) {
61        case SHORT_DATE_TIME:
62          modifiedCol = col;
63          break;
64        case MEMO:
65          valueCol = col;
66          break;
67        default:
68          // ignore
69        }
70      }
71  
72      _valueCol = valueCol;
73      _modifiedCol = modifiedCol;
74    }
75  
76    @Override
77    public void postTableLoadInit() throws IOException {
78      super.postTableLoadInit();
79  
80      // link up with the actual versioned column.  it should have the same name
81      // as the "value" column in the type table.
82      Column versionedCol = getColumn().getTable().getColumn(
83          getValueColumn().getName());
84      ((ColumnImpl)versionedCol).setVersionHistoryColumn((ColumnImpl)getColumn());
85    }
86      
87    public Column getValueColumn() {
88      return _valueCol;
89    }
90  
91    public Column getModifiedDateColumn() {
92      return _modifiedCol;
93    }
94    
95    @Override
96    public ComplexDataType getType() {
97      return ComplexDataType.VERSION_HISTORY;
98    }
99  
100   @Override
101   public ComplexValue.Id updateValue(Version value) throws IOException {
102     throw new UnsupportedOperationException(
103         "This column does not support value updates");
104   }
105 
106   @Override
107   public void deleteValue(Version value) throws IOException {
108     throw new UnsupportedOperationException(
109         "This column does not support value deletes");
110   }
111 
112   @Override
113   public void deleteAllValues(int complexValueFk) throws IOException {
114     throw new UnsupportedOperationException(
115         "This column does not support value deletes");
116   }
117 
118   @Override
119   protected List<Version> toValues(ComplexValueForeignKey complexValueFk,
120                                    List<Row> rawValues)
121     throws IOException
122   {
123     List<Version> versions = super.toValues(complexValueFk, rawValues);
124 
125     // order versions newest to oldest
126     Collections.sort(versions);
127     
128     return versions;
129   }
130 
131   @Override
132   protected VersionImpl toValue(ComplexValueForeignKey complexValueFk,
133                                 Row rawValue) {
134     ComplexValue.Id id = getValueId(rawValue);
135     String value = (String)getValueColumn().getRowValue(rawValue);
136     Date modifiedDate = (Date)getModifiedDateColumn().getRowValue(rawValue);
137 
138     return new VersionImpl(id, complexValueFk, value, modifiedDate);
139   }
140 
141   @Override
142   protected Object[] asRow(Object[] row, Version version) throws IOException {
143     super.asRow(row, version);
144     getValueColumn().setRowValue(row, version.getValue());
145     getModifiedDateColumn().setRowValue(row, version.getModifiedDate());
146     return row;
147   }
148   
149   public static Version newVersion(String value, Date modifiedDate) {
150     return newVersion(INVALID_FK, value, modifiedDate);
151   }
152   
153   public static Version newVersion(ComplexValueForeignKey complexValueFk,
154                                    String value, Date modifiedDate) {
155     return new VersionImpl(INVALID_ID, complexValueFk, value, modifiedDate);
156   }
157 
158 
159   private static class VersionImpl extends ComplexValueImpl implements Version
160   {
161     private final String _value;
162     private final Date _modifiedDate;
163 
164     private VersionImpl(Id id, ComplexValueForeignKey complexValueFk,
165                         String value, Date modifiedDate)
166     {
167       super(id, complexValueFk);
168       _value = value;
169       _modifiedDate = modifiedDate;
170     }
171     
172     public String getValue() {
173       return _value;
174     }
175 
176     public Date getModifiedDate() {
177       return _modifiedDate;
178     }    
179     
180     public int compareTo(Version o) {
181       Date d1 = getModifiedDate();
182       Date d2 = o.getModifiedDate();
183 
184       // sort by descending date (newest/greatest first)
185       int cmp = d2.compareTo(d1);
186       if(cmp != 0) {
187         return cmp;
188       }
189 
190       // use id, then complexValueFk to break ties (although we really
191       // shouldn't be comparing across different columns)
192       int id1 = getId().get();
193       int id2 = o.getId().get();
194       if(id1 != id2) {
195         return ((id1 > id2) ? -1 : 1);
196       }
197       id1 = getComplexValueForeignKey().get();
198       id2 = o.getComplexValueForeignKey().get();
199       return ((id1 > id2) ? -1 :
200               ((id1 < id2) ? 1 : 0));
201     }
202 
203     public void update() throws IOException {
204       throw new UnsupportedOperationException(
205           "This column does not support value updates");
206     }
207     
208     public void delete() throws IOException {
209       throw new UnsupportedOperationException(
210           "This column does not support value deletes");
211     }
212 
213     @Override
214     public String toString()
215     {
216       return "Version(" + getComplexValueForeignKey() + "," + getId() + ") " +
217         getModifiedDate() + ", " + getValue();
218     } 
219   }
220   
221 }