View Javadoc
1   package fr.ifremer.tutti.ui.swing.content.actions;
2   
3   /*
4    * #%L
5    * Tutti :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2012 - 2016 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU General Public License as
13   * published by the Free Software Foundation, either version 3 of the
14   * License, or (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU General Public
22   * License along with this program.  If not, see
23   * <http://www.gnu.org/licenses/gpl-3.0.html>.
24   * #L%
25   */
26  
27  
28  import java.sql.Connection;
29  import java.sql.DriverManager;
30  import java.sql.PreparedStatement;
31  import java.sql.ResultSet;
32  
33  /**
34   * Class a utiliser pour re-calculer tous les rank_order de tous les enfants
35   * d'un lots (table batch)
36   *
37   * Quelque fois la base est corrompu et un meme rank_order est utilise plusieurs
38   * fois pour des enfants differents d'un lots. Ce script conserve le plus
39   * possible l'existant tout en mettant des rank_order pour tous les enfants
40   *
41   * @author poussin
42   * @version $Revision$
43   *
44   * Last update: $Date$
45   * by : $Author$
46   */
47  public class FixesBatchRankOrder {
48  
49      protected boolean commit;
50  
51      static public void main(String... args) throws Exception {
52          if (args.length <= 0 || ("-nocommit".equals(args[0]) && args.length <= 1)) {
53              System.err.println("usage: FixesBatchRankOrder -nocommit <db file path> [login] [password]");
54          } else {
55              int i=0;
56              boolean commit = true;
57              if ("-nocommit".equals(args[0])) {
58                  commit = false;
59                  i++;
60              }
61              String dbPath = args[i++];
62              String login = args.length > i ? args[i++] : "SA";
63              String password = args.length > i ? args[i++] : "";
64              new FixesBatchRankOrder(commit).doAction(dbPath, login, password);
65          }
66      }
67  
68      public FixesBatchRankOrder() {
69          this(true);
70      }
71  
72      /**
73       * @param commit if true commit modification, if false then rollback modification
74       */
75      public FixesBatchRankOrder(boolean commit) {
76          this.commit = commit;
77      }
78  
79      /**
80       * on fait l'action en creant une nouvelle connexion sur la base de donnees
81       * Cette connexion est commitee fermee a la fin.
82       *
83       * @param dbPath
84       * @param login
85       * @param password
86       * 
87       * @throws Exception
88       */
89      public void doAction(String dbPath, String login, String password) throws Exception {
90          System.out.println("FixesRankOrder for db: " + dbPath);
91  
92          Class.forName("org.hsqldb.jdbcDriver" );
93          try (Connection c = DriverManager.getConnection(
94                  String.format("jdbc:hsqldb:file:%s;ifexists=true;shutdown=true", dbPath),
95                  login,
96                  password)) {
97              doAction(c);
98          }
99      }
100 
101     /**
102      * On fait l'action sur la connection passee en parametre
103      *
104      * @param c
105      * @throws Exception
106      */
107     public void doAction(Connection c) throws Exception {
108         boolean autoCommit = c.getAutoCommit();
109         try {
110             c.setAutoCommit(false);
111 
112             // recherche tous les 'batch' avec des enfants en conflit sur le rank_order
113             PreparedStatement catchWithError = c.prepareStatement(
114                     "SELECT b1.parent_batch_fk as pid, count(b1.id) as conflict"
115                             + " FROM BATCH b1, BATCH b2"
116                             + " WHERE b1.parent_batch_fk = b2.parent_batch_fk and b1.raNK_ORDER=b2.rank_order and b1.id != b2.id group by b1.parent_batch_fk"
117                             + " ORDER BY b1.parent_batch_fk");
118             ResultSet rs = catchWithError.executeQuery();
119             while (rs.next()) {
120                 int id = rs.getInt("pid");
121                 int conflict = rs.getInt("conflict");
122                 fixesRankOrder(c, id, conflict);
123             }
124             if (commit) {
125                 c.commit();
126                 System.out.println("Modification commited");
127             } else {
128                 c.rollback();
129                 System.out.println("Modification reverted");
130             }
131         } finally {
132             c.setAutoCommit(autoCommit);
133         }
134     }
135 
136     /**
137      * recalcul le rank_order de chaque enfant du lot passe parametre.
138      * La modification est faite, mais si la connection n'est pas en autoCommit
139      * il faut encore faire le commit apres son appel pour que le changement
140      * soit reelement effectif.
141      *
142      * @param c la connexion JDBC
143      * @param id l'id du lot pere
144      * @param conflict le nombre de conflit (optionnel)
145      * @return le nombre de fils dont le rank_order a ete recalcule.
146      * 
147      * @throws Exception 
148      */
149     protected int fixesRankOrder(Connection c, int id, int conflict) throws Exception {
150         System.out.println(String.format("FixesRankOrder catch id: %s with %s conflicts ", id, conflict));
151 
152         String query = "update batch set rank_order = (" +
153                 "select count(id) from batch b2 where batch.parent_batch_fk = b2.parent_batch_fk and convert(concat(concat(b2.rank_order, '.'), b2.id), DECIMAL)  < convert(concat(concat(batch.rank_order, '.'), batch.id), DECIMAL) ) +1" +
154                 "where PARENT_BATCH_FK = ?";
155 
156 
157         PreparedStatement update = c.prepareStatement(query);
158         update.setInt(1, id);
159         int result = update.executeUpdate();
160         
161         System.out.println(String.format("..... %s children reordered", result));
162         return result;
163     }
164 }