1 package com.melloware.jukes.db;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileOutputStream;
6 import java.sql.Connection;
7 import java.sql.SQLException;
8 import java.sql.Statement;
9 import java.util.zip.Deflater;
10 import java.util.zip.ZipEntry;
11 import java.util.zip.ZipOutputStream;
12
13 import org.apache.commons.io.FileUtils;
14 import org.apache.commons.io.FilenameUtils;
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.hsqldb.Server;
18 import org.hsqldb.ServerConstants;
19
20 import com.melloware.jukes.exception.InfrastructureException;
21
22
23
24
25
26
27
28
29
30
31
32 public final class Database {
33
34 private static final Log LOG = LogFactory.getLog(Database.class);
35 private static Server server = null;
36 private static String jdbcUrl = null;
37 private static String databaseLocation = null;
38 private static String databaseAlias = null;
39
40
41
42
43 private Database () {
44 super();
45 }
46
47
48
49
50
51 public static String getJdbcURL() {
52 if (LOG.isInfoEnabled()) {
53 LOG.info("JDBC URL: " + jdbcUrl);
54 }
55 return jdbcUrl;
56 }
57
58
59
60
61
62
63
64
65
66
67
68
69 public static void setWriteDelay(final Connection connection, final String writeDelay) {
70 Statement stmt = null;
71 try {
72 stmt = connection.createStatement();
73 final String sql = "SET WRITE_DELAY " + writeDelay + ";";
74 LOG.debug(sql);
75 stmt.execute(sql);
76 } catch (SQLException ex) {
77 LOG.error(ex.getMessage(), ex);
78 } finally {
79 if (stmt != null) {
80 try {
81 stmt.close();
82 } catch (SQLException ex) {
83 LOG.error(ex.getMessage(), ex);
84 throw new InfrastructureException(ex);
85 }
86 }
87 }
88
89 }
90
91
92
93
94
95
96
97 public static void backupDatabase(final Connection aConnection, final String aZipLocation) {
98 if (LOG.isInfoEnabled()) {
99 LOG.info("Backing up database to " + aZipLocation);
100 }
101
102
103 executeSQL(aConnection, "CHECKPOINT DEFRAG");
104
105
106 final String location = databaseLocation;
107 final String[] filesToZip = new String[4];
108 filesToZip[0] = location + ".backup";
109 filesToZip[1] = location + ".properties";
110 filesToZip[2] = location + ".script";
111
112
113 filesToZip[3] = databaseAlias + ".data";
114
115 final byte[] buffer = new byte[18024];
116
117 try {
118 final File zipFile = new File(aZipLocation);
119
120
121 if (!zipFile.exists()) {
122 final String path = FilenameUtils.getFullPathNoEndSeparator(aZipLocation);
123 FileUtils.forceMkdir(new File(path));
124 }
125
126 final ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
127
128
129 out.setLevel(Deflater.BEST_COMPRESSION);
130
131
132 for (int i = 0; i < filesToZip.length; i++) {
133 final String filename = filesToZip[i];
134 LOG.info("Zipping " + filename);
135
136
137 out.putNextEntry(new ZipEntry(FilenameUtils.getName(filename)));
138
139 File file = new File(filename);
140 FileInputStream in = null;
141 if (file.exists()) {
142 in = new FileInputStream(file);
143
144
145 int len;
146 while ((len = in.read(buffer)) > 0) {
147 out.write(buffer, 0, len);
148 }
149
150
151 in.close();
152 }
153
154
155 out.closeEntry();
156 }
157
158
159 out.close();
160 } catch (Exception ex) {
161 throw new InfrastructureException(ex);
162 }
163 }
164
165
166
167
168
169
170
171 public static void executeSQL(final Connection connection, final String sql) {
172 if (LOG.isDebugEnabled()) {
173 LOG.debug("Executing SQL: " + sql);
174 }
175
176 Statement stmt = null;
177 try {
178 stmt = connection.createStatement();
179 LOG.debug(sql);
180 stmt.execute(sql);
181 } catch (SQLException ex) {
182 LOG.error(ex.getMessage(), ex);
183 throw new InfrastructureException(ex);
184 } finally {
185 if (stmt != null) {
186 try {
187 stmt.close();
188 } catch (SQLException ex) {
189 LOG.error(ex.getMessage(), ex);
190 throw new InfrastructureException(ex);
191 }
192 }
193 }
194 }
195
196
197
198
199 public static void shutdown() {
200 shutdownHSQLDB();
201 }
202
203
204
205
206 public static void startup(final String location, final String alias) {
207 databaseLocation = location;
208 databaseAlias = alias;
209 startupHSQLDB(location, alias);
210 }
211
212
213
214
215 private static void shutdownHSQLDB() {
216 try {
217 if (server != null) {
218 LOG.info("Shutting down HSQLDB Server.");
219 server.stop();
220 while (server.getState() != ServerConstants.SERVER_STATE_SHUTDOWN) {
221 try {
222 LOG.debug("Sleeping waiting for server to stop");
223 Thread.sleep(100);
224 } catch (InterruptedException e) {
225 LOG.debug("Interrupted");
226 }
227 }
228 server = null;
229 }
230
231 } catch (RuntimeException ex) {
232 LOG.error(ex.getMessage(), ex);
233 throw new InfrastructureException(ex);
234 }
235 }
236
237
238
239
240
241
242
243 private static void startupHSQLDB(final String location, final String alias) {
244 try {
245 LOG.info("Starting up HSQLDB Server.");
246 jdbcUrl = "jdbc:hsqldb:hsql://localhost/" + alias;
247 server = new Server();
248
249 if (LOG.isInfoEnabled()) {
250 LOG.info("Location: " + location);
251 LOG.info(server.getProductName() + " " + server.getProductVersion());
252 }
253
254 server.setDatabaseName(0, alias);
255 server.setDatabasePath(0,
256 "file:" + location
257 + ";runtime.gc_interval=10000;hsqldb.default_table_type=cached;");
258 server.setLogWriter(null);
259 server.setErrWriter(null);
260 server.setSilent(true);
261 server.setTrace(false);
262 server.start();
263
264 System.getProperties().put("db.product", server.getProductName());
265 System.getProperties().put("db.version", server.getProductVersion());
266 System.getProperties().put("db.address", server.getAddress());
267
268 } catch (RuntimeException ex) {
269 LOG.error(ex.getMessage(), ex);
270 throw new InfrastructureException(ex);
271 }
272 }
273
274 }