KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdo > tools > ant > SchemaMigrationBean


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdo.tools.ant;
13
14 import com.versant.core.jdbc.sql.diff.ControlParams;
15 import com.versant.core.jdbc.sql.SqlDriver;
16 import com.versant.core.jdbc.JdbcStorageManagerFactory;
17 import com.versant.core.jdbc.JdbcConnectionSource;
18 import com.versant.core.common.config.ConfigParser;
19 import com.versant.core.common.config.ConfigInfo;
20 import com.versant.core.storagemanager.StorageManagerFactory;
21 import com.versant.core.storagemanager.StorageManagerFactoryBuilder;
22
23 import java.util.Properties JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Date JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.io.*;
28 import java.text.SimpleDateFormat JavaDoc;
29 import java.sql.Connection JavaDoc;
30 import java.sql.SQLException JavaDoc;
31 import java.sql.Statement JavaDoc;
32
33 /**
34  */

35 public class SchemaMigrationBean {
36     private ConfigInfo config;
37     private Properties JavaDoc properties;
38     private String JavaDoc propertiesResourceName = "versant.properties";
39     private File propertiesFile;
40
41     private StorageManagerFactory smf;
42
43     private ControlParams params = null;
44     private boolean checkLength = true;
45     private boolean checkType = true;
46     private boolean checkScale = true;
47     private boolean checkNulls = true;
48     private boolean checkPK = true;
49     private boolean checkIndex = true;
50     private boolean checkConstraint = true;
51     private boolean checkExtraColumns = true;
52     private File outputDir = null;
53     private boolean direct = false;
54     private String JavaDoc datastoreName;
55     private boolean logEventsToSysOut = true;
56     private PrintStream out = System.out;
57
58     /**
59      * Returns the output PrintStream
60      */

61     public PrintStream getOut() {
62         return out;
63     }
64     /**
65      * Set the logging PrintStream (System.out by default)
66      */

67     public void setOut(PrintStream out) {
68         this.out = out;
69     }
70
71     public boolean isLogEventsToSysOut() {
72         return logEventsToSysOut;
73     }
74
75     /**
76      * Must every thing be logged to System.out (true by default)
77      */

78     public void setLogEventsToSysOut(boolean logEventsToSysOut) {
79         this.logEventsToSysOut = logEventsToSysOut;
80     }
81
82     /**
83      * Is the constraints of the tables checked.
84      */

85     public boolean isCheckConstraint() {
86         return checkConstraint;
87     }
88
89     /**
90      * Must the constraints of the tables be checked.
91      */

92     public void setCheckConstraint(boolean checkConstraint) {
93         this.checkConstraint = checkConstraint;
94     }
95
96     /**
97      * Is the extra columns of the table checked.
98      */

99     public boolean isCheckExtraColumns() {
100         return checkExtraColumns;
101     }
102
103     /**
104      * Must the extra columns of the table be checked.
105      */

106     public void setCheckExtraColumns(boolean checkExtraColumns) {
107         this.checkExtraColumns = checkExtraColumns;
108     }
109
110     /**
111      * Is the indexes of the tables checked.
112      */

113     public boolean isCheckIndex() {
114         return checkIndex;
115     }
116
117     /**
118      * Must the indexes of the tables be checked.
119      */

120     public void setCheckIndex(boolean checkIndex) {
121         this.checkIndex = checkIndex;
122     }
123
124     /**
125      * Is the lenght of the columns checked.
126      */

127     public boolean isCheckLength() {
128         return checkLength;
129     }
130
131     /**
132      * Must the lenght of the columns be checked.
133      */

134     public void setCheckLength(boolean checkLength) {
135         this.checkLength = checkLength;
136     }
137
138     /**
139      * Is the null values of the columns checked.
140      */

141     public boolean isCheckNulls() {
142         return checkNulls;
143     }
144
145     /**
146      * Must the null values of the columns be checked.
147      */

148     public void setCheckNulls(boolean checkNulls) {
149         this.checkNulls = checkNulls;
150     }
151
152     /**
153      * Is the primary keys of the tables checked.
154      */

155     public boolean isCheckPK() {
156         return checkPK;
157     }
158
159     /**
160      * Must the primary keys of the tables be checked.
161      */

162     public void setCheckPK(boolean checkPK) {
163         this.checkPK = checkPK;
164     }
165
166     /**
167      * Is the scale of the columns checked.
168      */

169     public boolean isCheckScale() {
170         return checkScale;
171     }
172
173     /**
174      * Must the scale of the columns be checked.
175      */

176     public void setCheckScale(boolean checkScale) {
177         this.checkScale = checkScale;
178     }
179
180     /**
181      * Is the types of the columns checked.
182      */

183     public boolean isCheckType() {
184         return checkType;
185     }
186
187     /**
188      * Must the types of the columns be checked.
189      */

190     public void setCheckType(boolean checkType) {
191         this.checkType = checkType;
192     }
193
194     /**
195      * Gets the datastore name.
196      */

197     public String JavaDoc getDatastoreName() {
198         return datastoreName;
199     }
200
201     /**
202      * Sets the datastore name i.e. store0,
203      * if this property is not set, then the first datastore will be used.
204      */

205     public void setDatastoreName(String JavaDoc datastoreName) {
206         this.datastoreName = datastoreName;
207     }
208
209     /**
210      * Will the script be executed directly.
211      */

212     public boolean isDirect() {
213         return direct;
214     }
215     /**
216      * Must the script be generated and executed directly?
217      */

218     public void setDirect(boolean direct) {
219         this.direct = direct;
220     }
221
222     public File getOutputDir() {
223         return outputDir;
224     }
225     /**
226      * Where must the script be generated to.
227      */

228     public void setOutputDir(File outputDir) {
229         this.outputDir = outputDir;
230     }
231
232     /**
233      * Get the jdogenie properties.
234      */

235
236     public Properties JavaDoc getProperties() {
237         return properties;
238     }
239
240     /**
241      * Sets the jdogenie properties, these are the same properies that are in
242      * the *.jdogenie properties file.
243      */

244     public void setProperties(Properties JavaDoc properties) {
245         if (config != null){
246             // throw exe
247
}
248         this.properties = properties;
249         ConfigParser parser = new ConfigParser();
250         config = parser.parse(properties);
251         config.validate();
252     }
253
254     /**
255      * Get the *.jdogenie property file
256      */

257     public File getPropertiesFile() {
258         return propertiesFile;
259     }
260
261     /**
262      * Sets the *.jdogenie property as a file.
263      */

264     public void setPropertiesFile(File propertiesFile) {
265         if (config != null) {
266             // throw exe
267
}
268         this.propertiesFile = propertiesFile;
269         ConfigParser parser = new ConfigParser();
270         config = parser.parseResource(propertiesFile);
271         config.validate();
272     }
273
274     /**
275      * Gets the *.jdogenie property file resource name
276      */

277     public String JavaDoc getPropertiesResourceName() {
278         return propertiesResourceName;
279     }
280
281     /**
282      * Sets the *.jdogenie property filename as a resource.
283      */

284     public void setPropertiesResourceName(String JavaDoc propertiesResourceName) {
285         if (config != null) {
286             // throw exe
287
}
288         this.propertiesResourceName = propertiesResourceName;
289         ConfigParser parser = new ConfigParser();
290         config = parser.parseResource(propertiesResourceName);
291         config.validate();
292     }
293
294     private void init() {
295
296
297         Thread.currentThread().setContextClassLoader(getClassLoader());
298
299
300
301
302         StorageManagerFactoryBuilder b = new StorageManagerFactoryBuilder();
303         b.setConfig(config);
304         b.setLoader(getClassLoader());
305         b.setFullInit(false);
306         smf = b.createStorageManagerFactory();
307
308         params = new ControlParams();
309         params.setCheckConstraint(checkConstraint);
310         params.setCheckExtraColumns(checkExtraColumns);
311         params.setCheckIndex(checkIndex);
312         params.setCheckLength(checkLength);
313         params.setCheckNulls(checkNulls);
314         params.setCheckPK(checkPK);
315         params.setCheckScale(checkScale);
316         params.setCheckType(checkType);
317     }
318
319     private ClassLoader JavaDoc getClassLoader() {
320         ClassLoader JavaDoc taskClassLoader = getClass().getClassLoader();
321         if (taskClassLoader == null) {
322             taskClassLoader = ClassLoader.getSystemClassLoader();
323         }
324         return taskClassLoader;
325     }
326
327     /**
328      * Migrate the given database, if direct is 'false' then just a script is
329      * generated.
330      * if direct is true, the the script is executed against the given datastore.
331      */

332     public void migrateDatabase() throws Exception JavaDoc {
333         String JavaDoc script = generateScript();
334         if (direct) {
335             JdbcConnectionSource conSrc =
336                     ((JdbcStorageManagerFactory)smf).getConnectionSource();
337             Connection JavaDoc con = null;
338             try {
339                 runScript(con, script);
340             } finally {
341                 if (con != null) {
342                     try {
343                         conSrc.returnConnection(con);
344                     } catch (SQLException JavaDoc e) {
345                         // ignore
346
}
347                 }
348             }
349         }
350     }
351
352     private String JavaDoc getFileName(SqlDriver sqlDriver) {
353         SimpleDateFormat JavaDoc formatter = new SimpleDateFormat JavaDoc("dd-MM-yyyy_H-m");
354         return "Schema_Migration_" + sqlDriver.getName() + "_" + formatter.format(new Date JavaDoc());
355     }
356
357     /**
358      * Generate the schema migration script, if there is no changes then an empty
359      * String is returned.
360      *
361      */

362     public String JavaDoc generateScript() throws Exception JavaDoc {
363         init();
364         JdbcStorageManagerFactory jsmf = (JdbcStorageManagerFactory)smf;
365         JdbcConnectionSource conSrc = jsmf.getConnectionSource();
366         Connection JavaDoc con = null;
367         FileOutputStream fout = null;
368         PrintWriter out1 = null;
369         try {
370             if (logEventsToSysOut) {
371                 out.println("Checking schema on " + conSrc.getURL());
372             }
373             StringWriter error = new StringWriter(10240);
374             PrintWriter perror = new PrintWriter(error, false);
375
376             StringWriter fix = new StringWriter(10240);
377             PrintWriter pfix = new PrintWriter(fix, false);
378
379
380             con = conSrc.getConnection(false, false);
381             boolean valid = jsmf.getSqlDriver().checkDDL(
382                     jsmf.getJdbcMetaData().getTables(), con, perror,pfix, params);
383             perror.close();
384             pfix.close();
385             if (valid) {
386                 if (logEventsToSysOut) {
387                     out.println("Schema is valid.");
388                 }
389                 return "";
390             } else {
391                 if (logEventsToSysOut) {
392                     out.println("Schema has errors.");
393                     out.println(error.toString());
394                 }
395                 error.close();
396                 if (outputDir != null) {
397                     String JavaDoc fileName = getFileName(jsmf.getSqlDriver()) + ".sql";
398                     if (logEventsToSysOut) {
399                         out.println("Writing file ("+ fileName +") to directory "+ outputDir);
400                     }
401                     File f = new File(outputDir, fileName);
402                     fout = new FileOutputStream(f);
403                     out1 = new PrintWriter(fout);
404                     out1.write(fix.toString());
405                     out1.flush();
406                     out1.close();
407                 }
408                 return fix.toString();
409             }
410         } finally {
411             if (con != null) {
412                 try {
413                     conSrc.returnConnection(con);
414                 } catch (SQLException JavaDoc e) {
415                     // ignore
416
}
417             }
418         }
419     }
420
421
422     private void runScript(Connection JavaDoc con, String JavaDoc script) throws Exception JavaDoc {
423             if (!con.getAutoCommit()) {
424                 con.rollback();
425                 con.setAutoCommit(true);
426             }
427
428             SQLScriptParser shredder = new SQLScriptParser();
429             ArrayList JavaDoc list = shredder.parse(script, true);
430             for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();) {
431                 SQLScriptParser.SQLScriptPart scriptPart = (SQLScriptParser.SQLScriptPart) iter.next();
432                 if (logEventsToSysOut) {
433                     out.println("Executing: \n" + scriptPart.getSql());
434                 }
435                 Statement JavaDoc stat = null;
436                 try {
437                     stat = con.createStatement();
438                     stat.execute(scriptPart.getSql());
439                 } finally {
440                     try {
441                         stat.close();
442                     } catch (SQLException JavaDoc e) {
443                         //hide
444
}
445                 }
446             }
447     }
448
449     /**
450      * Execute the given script agains the datastore
451      */

452     public void executeScript(String JavaDoc script) throws Exception JavaDoc {
453         init();
454         JdbcConnectionSource conSrc =
455                 ((JdbcStorageManagerFactory)smf).getConnectionSource();
456         Connection JavaDoc con = null;
457         try {
458             runScript(con, script);
459         } finally {
460             if (con != null) {
461                 try {
462                     conSrc.returnConnection(con);
463                 } catch (SQLException JavaDoc e) {
464                     // ignore
465
}
466             }
467         }
468     }
469
470
471
472 }
473
Popular Tags