Source code: openfuture/bugbase/domain/update/IntroduceGroupsUpdate.java
1 package openfuture.bugbase.domain.update;
2 /*
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.<p>
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.<p>
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br>
16 * http://www.gnu.org/copyleft/lesser.html
17 */
18
19 import java.sql.Connection;
20 import java.sql.SQLException;
21 import java.sql.Statement;
22 import java.text.ParseException;
23 import java.text.SimpleDateFormat;
24 import java.util.Iterator;
25 import java.util.LinkedList;
26 import java.util.ListIterator;
27 import openfuture.bugbase.domain.Persistency;
28 import openfuture.bugbase.model.Transaction;
29 import openfuture.bugbase.model.TransactionResult;
30 import openfuture.bugbase.model.Version;
31 import openfuture.bugbase.model.VersionUpdate;
32 import openfuture.util.database.DBServer;
33
34 // Configuration Management Information:
35 // -------------------------------------
36 // $Id: IntroduceGroupsUpdate.java,v 1.3 2001/07/01 06:46:30 wreissen Exp $
37 //
38 // Version History:
39 // ----------------
40 // $Log: IntroduceGroupsUpdate.java,v $
41 // Revision 1.3 2001/07/01 06:46:30 wreissen
42 // fixed errors in DOS/Unix-translation.
43 //
44 // Revision 1.3 2001/06/26 12:09:01 wreissen
45 // table names in lowercase.
46 //
47 // Revision 1.2 2001/03/26 15:44:15 wreissen
48 // tableExists moved from Persistency to DBServer
49 //
50 // Revision 1.1 2000/09/27 15:53:24 wreissen
51 // moved to openfuture.
52 //
53 // Revision 1.5 2000/08/28 10:20:40 wreissen
54 // the Persistency holds the database connection statically.
55 //
56 // Revision 1.4 2000/07/12 08:18:15 wreissen
57 // All connection relevant methods obtain the connection as argument,
58 // since user sessions are introduced.
59 //
60 // Revision 1.3 2000/06/27 15:23:49 wreissen
61 // minor changes.
62 //
63 // Revision 1.2 2000/06/15 05:00:46 wreissen
64 // documentation improved.
65 //
66 // Revision 1.1 2000/06/13 05:04:37 wreissen
67 // initial version
68 //
69 //
70 // ***********************************************************************************
71 /**
72 * All bug reports belong to a user group. This way it is possible to
73 * restrict the access to bug reports to a certain group.
74 *
75 *
76 * Created: Mon Jun 12 20:06:16 2000
77 *
78 * @author Wolfgang Reissenberger
79 * @version $Revision: 1.3 $
80 */
81
82 public class IntroduceGroupsUpdate implements VersionUpdate {
83
84 private Version version;
85 private Connection connection;
86 private Persistency persistency;
87 private LinkedList columns;
88 private LinkedList coltypes;
89 private String backupTable;
90
91 public IntroduceGroupsUpdate(Persistency persistency) {
92 SimpleDateFormat df = new SimpleDateFormat("y-M-d HH:mm");
93 try {
94 version = new Version("0.4.5", df.parse("2000-06-12 20:08"));
95 } catch (ParseException e) {
96 version = new Version("0.4.5", null);
97 }
98 this.persistency = persistency;
99 backupTable = "bugreports_backup";
100 }
101
102 // implementation of openfuture.bugbase.model.Transaction interface
103
104 /**
105 * Setup before the transaction core is executed.
106 * <ul>
107 * <li> Copy the table bugreports to bugreports_backup.
108 * </ul>
109 *
110 *
111 * @return result of the task
112 */
113 public TransactionResult setup() {
114 LinkedList logging = new LinkedList();
115 LinkedList warning = new LinkedList();
116 int result = TransactionResult.SUCCESS;
117
118 Statement statement = null;
119 try {
120 connection = persistency.getConnection();
121 statement = connection.createStatement();
122
123 // first we insure, that the backup table for bugreports
124 // does not exist.
125 if (persistency.getSqlServer().tableExists(connection, backupTable)) {
126 statement.executeUpdate("drop table " + backupTable);
127 logging.add("table " + backupTable + " exists ... dropped.");
128 }
129
130 // create bugreports_backup
131 columns = new LinkedList();
132 columns.add("id");
133 columns.add("project");
134 columns.add("title");
135 columns.add("description");
136 columns.add("packageName");
137 columns.add("errorLevel");
138 columns.add("dateReported");
139 columns.add("dateStarted");
140 columns.add("dateFixed");
141 columns.add("dateRejected");
142 columns.add("emailReporter");
143 columns.add("emailDoctor");
144
145 coltypes = new LinkedList();
146 coltypes.add("integer " +
147 persistency.getSqlServer().sqlTranslate(DBServer.AUTO_INCREMENT)
148 + " not null");
149 coltypes.add(persistency.getSqlServer().sqlTranslate("varchar(50)"));
150 coltypes.add(persistency.getSqlServer().sqlTranslate("varchar(20)"));
151 coltypes.add(persistency.getSqlServer().sqlTranslate("varchar(100)"));
152 coltypes.add(persistency.getSqlServer().sqlTranslate(DBServer.BLOB));
153 coltypes.add(persistency.getSqlServer().sqlTranslate("varchar(50)"));
154 coltypes.add("integer");
155 coltypes.add("datetime");
156 coltypes.add("datetime");
157 coltypes.add("datetime");
158 coltypes.add("datetime");
159 coltypes.add(persistency.getSqlServer().sqlTranslate("varchar(100)"));
160 coltypes.add(persistency.getSqlServer().sqlTranslate("varchar(100)"));
161
162 persistency.createTable("bugreports_backup",
163 columns, coltypes, null);
164 logging.add("table " + backupTable + " created.");
165 // copy table bugreports
166 statement.executeUpdate("insert into " + backupTable +
167 " select * from bugreports");
168 logging.add("table bugreports copied to " + backupTable);
169
170 } catch (SQLException e) {
171 e.printStackTrace();
172 warning.add("setup failed. Reason: " + e.getMessage());
173 result = TransactionResult.FAILURE;
174 } finally {
175 try {
176 if (statement != null) statement.close();
177 } catch (SQLException e) {
178 e.printStackTrace();
179 warning.add("statement.close() failed. Reason: "
180 + e.getMessage());
181 result = TransactionResult.FAILURE;
182 }
183 }
184 return(new TransactionResult(result, logging, warning));
185 }
186
187 /**
188 * Core execution of the transaction.
189 * <ul>
190 * <li> drop table 'bugreports'
191 * <li> create it new with additional column 'groupid'.
192 * <li> copy entries from 'bugreports_backup' to 'bugreports'.
193 * <li> set all groupid attributes to 'users', if they are null
194 * </ul>
195 *
196 * @return result of the task
197 */
198 public TransactionResult execute() {
199 LinkedList logging = new LinkedList();
200 LinkedList warning = new LinkedList();
201 int result = TransactionResult.SUCCESS;
202
203 Statement statement = null;
204 try {
205 statement = connection.createStatement();
206
207 // drop table 'bugreports'
208 statement.executeUpdate("drop table bugreports");
209 logging.add("table bugreports dropped.");
210
211 // create it new with additional column 'groupid'
212 LinkedList newcolumns = new LinkedList();
213 LinkedList newcoltypes = new LinkedList();
214 newcolumns.add(columns.get(0));
215 newcolumns.add(columns.get(1));
216 newcoltypes.add(coltypes.get(0));
217 newcoltypes.add(coltypes.get(1));
218 newcolumns.add("groupid");
219 newcoltypes.add("varchar");
220
221 ListIterator it = columns.listIterator(2);
222 while (it.hasNext()) newcolumns.add(it.next());
223 it = coltypes.listIterator(2);
224 while (it.hasNext()) newcoltypes.add(it.next());
225 persistency.createTable("bugreports",
226 newcolumns, newcoltypes, null);
227 logging.add("table bugreports created with new column 'groupid'.");
228
229 // copy 'bugreports_backup' to 'bugreports'
230 String theColumns = join(", ", columns);
231 String sqlString = "insert into bugreports (" + theColumns + ")";
232 sqlString += " select " + theColumns + " from " + backupTable;
233 statement.executeUpdate(sqlString);
234 logging.add("table 'bugreports_backup' copied back to 'bugreports'.");
235 statement.executeUpdate("update bugreports set groupid = 'users' where groupid = null");
236 logging.add("bugreports belong to 'users' by default.");
237
238 } catch (SQLException e) {
239 e.printStackTrace();
240 warning.add("execute failed. Reason: " + e.getMessage());
241 result = TransactionResult.FAILURE;
242 } finally {
243 try {
244 if (statement != null) statement.close();
245 } catch (SQLException e) {
246 e.printStackTrace();
247 warning.add("statement.close() failed. Reason: "
248 + e.getMessage());
249 result = TransactionResult.FAILURE;
250 }
251 }
252 return(new TransactionResult(result, logging, warning));
253 }
254
255 /**
256 * This method will be executed after a successful execution of
257 * {@link #execute}.
258 * <ul>
259 * <li> drop table 'bugreports_backup'
260 * </ul>
261 *
262 * @return result of the task
263 */
264 public TransactionResult cleanup() {
265 LinkedList logging = new LinkedList();
266 LinkedList warning = new LinkedList();
267 int result = TransactionResult.SUCCESS;
268
269 Statement statement = null;
270 try {
271 statement = connection.createStatement();
272 statement.executeUpdate("drop table " + backupTable);
273 logging.add("table " + backupTable + " dropped.");
274
275 } catch (SQLException e) {
276 e.printStackTrace();
277 warning.add("cleanup failed. Reason: " + e.getMessage());
278 result = TransactionResult.FAILURE;
279 } finally {
280 try {
281 if (statement != null) statement.close();
282 } catch (SQLException e) {
283 e.printStackTrace();
284 warning.add("statement.close() failed. Reason: "
285 + e.getMessage());
286 result = TransactionResult.FAILURE;
287 }
288 }
289 persistency.setPersistencyVersion(version);
290
291 return(new TransactionResult(result, logging, warning));
292 }
293
294 /**
295 * This method will be executed after a unsuccessful execution of
296 * {@link #execute}.
297 * <ul>
298 * <li> copy table 'bugreports_backup' back to table 'bugreports'
299 * <li> drop table 'bugreports_backup'
300 * </ul>
301 *
302 * @return result of the task
303 */
304 public TransactionResult rollback() {
305 LinkedList logging = new LinkedList();
306 LinkedList warning = new LinkedList();
307 int result = TransactionResult.SUCCESS;
308
309 Statement statement = null;
310 try {
311 statement = connection.createStatement();
312
313 if (persistency.getSqlServer().tableExists(connection,
314 backupTable)) {
315 statement.executeUpdate("drop table bugreports");
316 logging.add("table bugreports dropped.");
317
318 persistency.createTable("bugreports",
319 columns, coltypes, null);
320 logging.add("table bugreports created with old structure.");
321
322 statement.executeUpdate("insert into bugreports select * from "
323 + backupTable);
324 logging.add("table " + backupTable + " copied to 'bugreports'");
325
326 statement.executeUpdate("drop table " + backupTable);
327 logging.add("table " + backupTable + " dropped.");
328 }
329
330 } catch (SQLException e) {
331 e.printStackTrace();
332 warning.add("rollback failed. Reason: " + e.getMessage());
333 result = TransactionResult.FAILURE;
334 } finally {
335 try {
336 if (statement != null) statement.close();
337 } catch (SQLException e) {
338 e.printStackTrace();
339 warning.add("statement.close() failed. Reason: "
340 + e.getMessage());
341 result = TransactionResult.FAILURE;
342 }
343 }
344
345 return(new TransactionResult(result, logging, warning));
346 }
347
348 /**
349 *
350 * @return <description>
351 */
352 public String getDescription() {
353 return "All bug reports belong to a user group. This way it is possible to restrict the access to bug reports to a certain group.";
354 }
355
356 /**
357 * No predecessor available.
358 * @return null
359 */
360 public final VersionUpdate predecessor() {
361 return null;
362 }
363
364 /**
365 * Persistency version after this update.
366 * @return version 0.4.5
367 */
368 public final Version getVersion() {
369 return this.version;
370 }
371
372
373 private String join (String separator, LinkedList strings) {
374
375 Iterator it = strings.iterator();
376
377 String result = "";
378 while (it.hasNext()) {
379 result += it.next().toString();
380 if (it.hasNext()) {
381 result += separator;
382 }
383 }
384 return result;
385 }
386
387
388 } // IntroduceGroups