File D:\maven-qcr-plugin-testsunitaires\qcr4java\h2-1.3.170-sources\target\site\qc\lecode\tools\Restore.java.html

1 /*
2 * Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
3 * Version 1.0, and under the Eclipse Public License, Version 1.0
4 * (http://h2database.com/html/license.html).
5 * Initial Developer: H2 Group
6 */
7 package org.h2.tools;
8
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.OutputStream;
12 import java.sql.SQLException;
13 import java.util.zip.ZipEntry;
14 import java.util.zip.ZipInputStream;
15
16 import org.h2.constant.SysProperties;
17 import org.h2.engine.Constants;
18 import org.h2.message.DbException;
19 import org.h2.store.fs.FileUtils;
20 import org.h2.util.IOUtils;
21 import org.h2.util.Tool;
22
23 /**
24 * Restores a H2 database by extracting the database files from a .zip file.
25 * @h2.resource
26 */
27 public class Restore extends Tool {
28
29 /**
30 * Options are case sensitive. Supported options are:
31 * <table>
32 * <tr><td>[-help] or [-?]</td>
33 * <td>Print the list of options</td></tr>
34 * <tr><td>[-file &lt;filename&gt;]</td>
35 * <td>The source file name (default: backup.zip)</td></tr>
36 * <tr><td>[-dir &lt;dir&gt;]</td>
37 * <td>The target directory (default: .)</td></tr>
38 * <tr><td>[-db &lt;database&gt;]</td>
39 * <td>The target database name (as stored if not set)</td></tr>
40 * <tr><td>[-quiet]</td>
41 * <td>Do not print progress information</td></tr>
42 * </table>
43 * @h2.resource
44 *
45 * @param args the command line arguments
46 */
47 public static void main(String... args) throws SQLException {
48 new Restore().runTool(args);
49 }
50
51 public void runTool(String... args) throws SQLException {
52 String zipFileName = "backup.zip";
53 String dir = ".";
54 String db = null;
55 for (int i = 0; args != null && i < args.length; i++) {
56 String arg = args[i];
57 if (arg.equals("-dir")) {
58 dir = args[++i];
59 } else if (arg.equals("-file")) {
60 zipFileName = args[++i];
61 } else if (arg.equals("-db")) {
62 db = args[++i];
63 } else if (arg.equals("-quiet")) {
64 // ignore
65 } else if (arg.equals("-help") || arg.equals("-?")) {
66 showUsage();
67 return;
68 } else {
69 showUsageAndThrowUnsupportedOption(arg);
70 }
71 }
72 execute(zipFileName, dir, db);
73 }
74
75 private static String getOriginalDbName(String fileName, String db) throws IOException {
76 InputStream in = null;
77 try {
78 in = FileUtils.newInputStream(fileName);
79 ZipInputStream zipIn = new ZipInputStream(in);
80 String originalDbName = null;
81 boolean multiple = false;
82 while (true) {
83 ZipEntry entry = zipIn.getNextEntry();
84 if (entry == null) {
85 break;
86 }
87 String entryName = entry.getName();
88 zipIn.closeEntry();
89 String name = getDatabaseNameFromFileName(entryName);
90 if (name != null) {
91 if (db.equals(name)) {
92 originalDbName = name;
93 // we found the correct database
94 break;
95 } else if (originalDbName == null) {
96 originalDbName = name;
97 // we found a database, but maybe another one
98 } else {
99 // we have found multiple databases, but not the correct
100 // one
101 multiple = true;
102 }
103 }
104 }
105 zipIn.close();
106 if (multiple && !db.equals(originalDbName)) {
107 throw new IOException("Multiple databases found, but not " + db);
108 }
109 return originalDbName;
110 } finally {
111 IOUtils.closeSilently(in);
112 }
113 }
114
115 /**
116 * Extract the name of the database from a given file name.
117 * Only files ending with .h2.db are considered, all others return null.
118 *
119 * @param fileName the file name (without directory)
120 * @return the database name or null
121 */
122 private static String getDatabaseNameFromFileName(String fileName) {
123 if (fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) {
124 return fileName.substring(0, fileName.length() - Constants.SUFFIX_PAGE_FILE.length());
125 }
126 return null;
127 }
128
129 /**
130 * Restores database files.
131 *
132 * @param zipFileName the name of the backup file
133 * @param directory the directory name
134 * @param db the database name (null for all databases)
135 * @throws DbException if there is an IOException
136 */
137 public static void execute(String zipFileName, String directory, String db) {
138 InputStream in = null;
139 try {
140 if (!FileUtils.exists(zipFileName)) {
141 throw new IOException("File not found: " + zipFileName);
142 }
143 String originalDbName = null;
144 int originalDbLen = 0;
145 if (db != null) {
146 originalDbName = getOriginalDbName(zipFileName, db);
147 if (originalDbName == null) {
148 throw new IOException("No database named " + db + " found");
149 }
150 if (originalDbName.startsWith(SysProperties.FILE_SEPARATOR)) {
151 originalDbName = originalDbName.substring(1);
152 }
153 originalDbLen = originalDbName.length();
154 }
155 in = FileUtils.newInputStream(zipFileName);
156 ZipInputStream zipIn = new ZipInputStream(in);
157 while (true) {
158 ZipEntry entry = zipIn.getNextEntry();
159 if (entry == null) {
160 break;
161 }
162 String fileName = entry.getName();
163 // restoring windows backups on linux and vice versa
164 fileName = fileName.replace('\\', SysProperties.FILE_SEPARATOR.charAt(0));
165 fileName = fileName.replace('/', SysProperties.FILE_SEPARATOR.charAt(0));
166 if (fileName.startsWith(SysProperties.FILE_SEPARATOR)) {
167 fileName = fileName.substring(1);
168 }
169 boolean copy = false;
170 if (db == null) {
171 copy = true;
172 } else if (fileName.startsWith(originalDbName + ".")) {
173 fileName = db + fileName.substring(originalDbLen);
174 copy = true;
175 }
176 if (copy) {
177 OutputStream o = null;
178 try {
179 o = FileUtils.newOutputStream(directory + SysProperties.FILE_SEPARATOR + fileName, false);
180 IOUtils.copy(zipIn, o);
181 o.close();
182 } finally {
183 IOUtils.closeSilently(o);
184 }
185 }
186 zipIn.closeEntry();
187 }
188 zipIn.closeEntry();
189 zipIn.close();
190 } catch (IOException e) {
191 throw DbException.convertIOException(e, zipFileName);
192 } finally {
193 IOUtils.closeSilently(in);
194 }
195 }
196
197 }
198