You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

VersionHistoryColumnInfoImpl.java 7.3KB

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