KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > tools > template > DatabaseMigrator


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
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 package scriptella.tools.template;
17
18 import scriptella.jdbc.GenericDriver;
19 import scriptella.jdbc.JdbcException;
20 import scriptella.spi.ConnectionParameters;
21
22 import java.sql.Connection JavaDoc;
23 import java.sql.DatabaseMetaData JavaDoc;
24 import java.sql.ResultSet JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.Arrays JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.LinkedHashSet JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Set JavaDoc;
33
34
35 /**
36  * TODO: Add documentation
37  *
38  * @author Fyodor Kupolov
39  * @version 1.0
40  */

41 public class DatabaseMigrator {
42     public static void main(final String JavaDoc args[]) {
43         //Currently this class is just a sample of how to generate a migration script template
44
//Rewite it
45

46         ConnectionParameters params = new ConnectionParameters(null,null);
47         GenericDriver jdbcDriver = new GenericDriver();
48
49
50         final Connection JavaDoc con = jdbcDriver.connect(params).getNativeConnection();
51         final Set JavaDoc<String JavaDoc> tables = sortTables(con, params);
52         StringBuilder JavaDoc o = new StringBuilder JavaDoc();
53         o.append("<etl>\n" +
54                 " <connection id=\"in\" driver=\"com.sybase.jdbc2.jdbc.SybDriver\" url=\"jdbc:sybase:Tds:localhost:2638\" user=\"DBA\" password=\"SQL\"/>\n" +
55                 " <connection id=\"out\" driver=\"org.hsqldb.jdbcDriver\" url=\"jdbc:hsqldb:file:D:/tools/hsqldb/data/dbm\" user=\"sa\" password=\"\"/>\n");
56
57         for (String JavaDoc t : tables) {
58             o.append(" <query connection-id=\"in\">\n")
59                     .append(" select ");
60             appendColumnNames(con, params, t, o).append(" from ").append(t);
61
62             o.append(" <script connection-id=\"out\">\n")
63                     .append(" insert into ").append(t).append("(");
64             appendColumnNames(con, params, t, o).append(") VALUES (");
65             appendColumnNames(con, params, t, o, ", ", "?").append(")")
66                     .append("\n </script>\n").
67             append("\n </query>\n");
68         }
69
70         o.append("</etl>\n");
71         System.out.println("o = " + o);
72
73         // JdbcUtils.getTableColumns(con, c,)
74
}
75
76     private static StringBuilder JavaDoc appendColumnNames(
77             final Connection JavaDoc con, ConnectionParameters params, final String JavaDoc table, final StringBuilder JavaDoc sql) {
78         return appendColumnNames(con, params, table, sql, ", ", "");
79     }
80
81     private static StringBuilder JavaDoc appendColumnNames(
82             final Connection JavaDoc con, ConnectionParameters params, final String JavaDoc table,
83             final StringBuilder JavaDoc sql, final String JavaDoc separator, final String JavaDoc prefix) {
84         final Set JavaDoc<String JavaDoc> tableColumns = getTableColumns(con, params, table);
85
86         for (Iterator JavaDoc<String JavaDoc> it = tableColumns.iterator(); it.hasNext();) {
87             String JavaDoc s = it.next();
88             sql.append(prefix);
89             sql.append(s);
90
91             if (it.hasNext()) {
92                 sql.append(separator);
93             }
94         }
95
96         return sql;
97     }
98
99     private static Set JavaDoc<String JavaDoc> sortTables(final Connection JavaDoc con, ConnectionParameters params) {
100         List JavaDoc<String JavaDoc> tables = getTables(con, params);
101         System.out.println("Sorting " + tables);
102
103         int n = tables.size();
104         int m[][] = new int[n][n];
105
106         for (int i = 0; i < m.length; i++) {
107             Arrays.fill(m[i], 0);
108         }
109
110         String JavaDoc tbls[] = tables.toArray(new String JavaDoc[n]);
111
112         try {
113             final DatabaseMetaData JavaDoc metaData = con.getMetaData();
114
115             for (int i = 0; i < n; i++) {
116                 String JavaDoc t = tbls[i];
117                 final ResultSet JavaDoc rs = metaData.getExportedKeys(params.getCatalog(),
118                         params.getSchema(), t);
119
120                 while (rs.next()) {
121                     // if (rs.getInt(11) != 2) { //Only not null FKs are taken into account
122
String JavaDoc t2 = rs.getString(7);
123                     int i2 = indexOf(tbls, t2);
124
125                     if (i2 >= 0) {
126                         m[i][i2] += ((rs.getInt(11) != 2) ? 10 : 1);
127                     }
128
129                     // }
130
}
131
132                 rs.close();
133             }
134
135             for (int i = 0; i < n; i++) {
136                 for (int j = 0; j < n; j++) {
137                     System.out.print(m[i][j]);
138                     System.out.print((m[i][j] >= 10) ? " " : " ");
139                 }
140
141                 System.out.println(tbls[i]);
142             }
143
144             boolean free[] = new boolean[n];
145             Arrays.fill(free, true);
146
147             Set JavaDoc<String JavaDoc> res = new LinkedHashSet JavaDoc<String JavaDoc>();
148
149             for (int i = 0; i < n; i++) {
150                 //on each i iteration we choose the best candidate (having minimal relationships)
151
int min = Integer.MAX_VALUE;
152                 int minI = -1;
153
154                 for (int j = 0; j < n; j++) { //choosing an available candidate
155

156                     int s = 0;
157
158                     if (free[j]) {
159                         for (int k = 0; k < n; k++) { //checking incoming relationships
160

161                             if ((k != j) && free[k]) {
162                                 s += m[k][j];
163                             }
164                         }
165
166                         if (s < min) {
167                             min = s;
168                             minI = j;
169                         }
170                     }
171                 }
172
173                 if (minI >= 0) {
174                     free[minI] = false;
175                     res.add(tbls[minI]);
176                 }
177             }
178
179             return res;
180         } catch (SQLException JavaDoc e) {
181             throw new JdbcException(e.getMessage(), e);
182         }
183     }
184
185     private static int indexOf(final String JavaDoc list[], final String JavaDoc element) {
186         for (int i = 0; i < list.length; i++) {
187             if (list[i].equalsIgnoreCase(element)) {
188                 return i;
189             }
190         }
191
192         return -1;
193     }
194
195     private static List JavaDoc<String JavaDoc> getTables(Connection JavaDoc con, ConnectionParameters params) {
196         try {
197             return getColumn(con.getMetaData()
198                     .getTables(con.getCatalog(),
199                     params.getSchema(), null, new String JavaDoc[]{"TABLE"}), 3);
200         } catch (SQLException JavaDoc e) {
201             throw new JdbcException(e.getMessage(), e);
202         }
203     }
204
205     private static Set JavaDoc<String JavaDoc> getTableColumns(Connection JavaDoc con, ConnectionParameters params, final String JavaDoc tableName) {
206         try {
207             return new HashSet JavaDoc<String JavaDoc>(getColumn(
208                     con.getMetaData()
209                             .getColumns(params.getCatalog(), params.getSchema(), tableName, null),
210                     4));
211         } catch (SQLException JavaDoc e) {
212             throw new JdbcException(e.getMessage(), e);
213         }
214     }
215
216     /**
217      * Iterates through the resultset and returns column values.
218      * @param rs resultset to iterate.
219      * @param columnPos column position. Starts at 1.
220      * @return list of column values.
221      */

222     public static List JavaDoc<String JavaDoc> getColumn(final ResultSet JavaDoc rs, final int columnPos) {
223         List JavaDoc<String JavaDoc> l = new ArrayList JavaDoc<String JavaDoc>();
224
225         try {
226             while (rs.next()) {
227                 l.add(rs.getString(columnPos));
228             }
229         } catch (SQLException JavaDoc e) {
230             throw new JdbcException("Unable to get column #" + columnPos, e);
231         }
232
233         return l;
234     }
235
236 }
237
Popular Tags