some javadoc and factory methods
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / v24_25 / SortIndexUpdater.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.database.update.v24_25;
11
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Set;
18
19 import org.apache.log4j.Logger;
20
21 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
22 import eu.etaxonomy.cdm.database.ICdmDataSource;
23 import eu.etaxonomy.cdm.database.update.ISchemaUpdaterStep;
24 import eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase;
25
26 /**
27 * @author a.mueller
28 * @date 16.09.2010
29 *
30 */
31 public class SortIndexUpdater extends SchemaUpdaterStepBase<SortIndexUpdater> implements ISchemaUpdaterStep {
32 @SuppressWarnings("unused")
33 private static final Logger logger = Logger.getLogger(SortIndexUpdater.class);
34
35 private String tableName;
36 private String sortIndexColumn;
37 private String parentColumn;
38 private boolean includeAudTable;
39 private Integer baseValue = 0;
40
41 public static final SortIndexUpdater NewInstance(String stepName, String tableName, String parentColumn, String sortIndexColumn, boolean includeAudTable){
42 return new SortIndexUpdater(stepName, tableName, parentColumn, sortIndexColumn, includeAudTable, 0);
43 }
44
45 protected SortIndexUpdater(String stepName, String tableName, String parentColumn, String sortIndexColumn, boolean includeAudTable, Integer baseValue) {
46 super(stepName);
47 this.tableName = tableName;
48 this.parentColumn = parentColumn;
49 this.sortIndexColumn = sortIndexColumn;
50 this.includeAudTable = includeAudTable;
51 this.baseValue = baseValue;
52 }
53
54 /* (non-Javadoc)
55 * @see eu.etaxonomy.cdm.database.update.SchemaUpdaterStepBase#invoke(eu.etaxonomy.cdm.database.ICdmDataSource, eu.etaxonomy.cdm.common.IProgressMonitor)
56 */
57 @Override
58 public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {
59 boolean result = true;
60 result &= addColumn(tableName, datasource, monitor);
61 if (includeAudTable){
62 String aud = "_AUD";
63 result &= addColumn(tableName + aud, datasource, monitor);
64 }
65 return (result == true )? 0 : null;
66 }
67
68 private boolean addColumn(String tableName, ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {
69
70 Map<Integer, Set<Integer>> indexMap = makeIndexMap(datasource);
71
72 updateIndices(tableName, datasource, indexMap);
73
74 return true;
75 }
76
77 /**
78 * @param datasource
79 * @param rs
80 * @param index
81 * @param oldParentId
82 * @return
83 * @throws SQLException
84 */
85 private Map<Integer, Set<Integer>> makeIndexMap(ICdmDataSource datasource) throws SQLException {
86 String resulsetQuery = "SELECT id, @parentColumn " +
87 " FROM @tableName " +
88 " WHERE @parentColumn IS NOT NULL " +
89 " ORDER BY @parentColumn, id";
90 resulsetQuery = resulsetQuery.replace("@tableName", tableName);
91 resulsetQuery = resulsetQuery.replace("@parentColumn", parentColumn);
92
93 ResultSet rs = datasource.executeQuery(resulsetQuery);
94 Integer index = baseValue;
95 int oldParentId = -1;
96
97
98 Map<Integer, Set<Integer>> indexMap = new HashMap<Integer, Set<Integer>>();
99 Integer counter = 0;
100 while (rs.next() ){
101 counter++;
102 int id = rs.getInt("id");
103 Object oParentId = rs.getObject(parentColumn);
104 if (oParentId != null){
105 int parentId = Integer.valueOf(oParentId.toString());
106 if (oldParentId != parentId){
107 index = baseValue;
108 oldParentId = parentId;
109 }else{
110 index++;
111 }
112 putIndex(id, index, indexMap);
113 }else{
114 logger.warn("This should not happen");
115 index = baseValue;
116 }
117 // System.out.println(oParentId + "," + id+","+ index+";");
118 }
119 return indexMap;
120 }
121
122 private void updateIndices(String tableName, ICdmDataSource datasource, Map<Integer, Set<Integer>> indexMap)
123 throws SQLException {
124 for (Integer index : indexMap.keySet()){
125 Set<Integer> set = indexMap.get(index);
126 String idSetString = makeIdSetString(set);
127
128 String updateQuery = "UPDATE @tableName SET @sortIndexColumn = @index WHERE id IN (@idList) ";
129 updateQuery = updateQuery.replace("@tableName", tableName);
130 updateQuery = updateQuery.replace("@sortIndexColumn", sortIndexColumn);
131 updateQuery = updateQuery.replace("@index", index.toString());
132 updateQuery = updateQuery.replace("@idList", idSetString);
133 datasource.executeUpdate(updateQuery);
134 }
135 }
136
137 private static String makeIdSetString(Set<Integer> set) {
138 StringBuffer result = new StringBuffer(set.size() * 5);
139 for (Integer id:set){
140 result.append(id + ",");
141 }
142 return result.substring(0, result.length() - 1);
143 }
144
145 private void putIndex(Integer id, Integer index, Map<Integer, Set<Integer>> indexMap) {
146 Set<Integer> set = indexMap.get(index);
147 if (set == null){
148 set = new HashSet<Integer>();
149 indexMap.put(index, set);
150 }
151 set.add(id);
152 }
153
154 }