EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.tools]

COVERAGE SUMMARY FOR SOURCE FILE [Backup.java]

nameclass, %method, %block, %line, %
Backup.java100% (1/1)100% (5/5)81%  (238/294)83%  (66.1/80)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Backup100% (1/1)100% (5/5)81%  (238/294)83%  (66.1/80)
execute (String, String, String, boolean): void 100% (1/1)71%  (10/14)60%  (3/5)
process (String, String, String, boolean): void 100% (1/1)80%  (148/185)84%  (41.1/49)
runTool (String []): void 100% (1/1)83%  (71/86)83%  (19/23)
Backup (): void 100% (1/1)100% (3/3)100% (1/1)
main (String []): void 100% (1/1)100% (6/6)100% (2/2)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.tools;
7 
8import java.io.FileNotFoundException;
9import java.io.IOException;
10import java.io.InputStream;
11import java.io.OutputStream;
12import java.sql.SQLException;
13import java.util.List;
14import java.util.zip.ZipEntry;
15import java.util.zip.ZipOutputStream;
16import org.h2.command.dml.BackupCommand;
17import org.h2.engine.Constants;
18import org.h2.message.DbException;
19import org.h2.store.FileLister;
20import org.h2.store.fs.FileUtils;
21import org.h2.util.IOUtils;
22import org.h2.util.Tool;
23 
24/**
25 * Creates a backup of a database.
26 * <br />
27 * This tool copies all database files. The database must be closed before using
28 * this tool. To create a backup while the database is in use, run the BACKUP
29 * SQL statement. In an emergency, for example if the application is not
30 * responding, creating a backup using the Backup tool is possible by using the
31 * quiet mode. However, if the database is changed while the backup is running
32 * in quiet mode, the backup could be corrupt.
33 *
34 * @h2.resource
35 */
36public class Backup extends Tool {
37 
38    /**
39     * Options are case sensitive. Supported options are:
40     * <table>
41     * <tr><td>[-help] or [-?]</td>
42     * <td>Print the list of options</td></tr>
43     * <tr><td>[-file &lt;filename&gt;]</td>
44     * <td>The target file name (default: backup.zip)</td></tr>
45     * <tr><td>[-dir &lt;dir&gt;]</td>
46     * <td>The source directory (default: .)</td></tr>
47     * <tr><td>[-db &lt;database&gt;]</td>
48     * <td>Source database; not required if there is only one</td></tr>
49     * <tr><td>[-quiet]</td>
50     * <td>Do not print progress information</td></tr>
51     * </table>
52     * @h2.resource
53     *
54     * @param args the command line arguments
55     */
56    public static void main(String... args) throws SQLException {
57        new Backup().runTool(args);
58    }
59 
60    @Override
61    public void runTool(String... args) throws SQLException {
62        String zipFileName = "backup.zip";
63        String dir = ".";
64        String db = null;
65        boolean quiet = false;
66        for (int i = 0; args != null && i < args.length; i++) {
67            String arg = args[i];
68            if (arg.equals("-dir")) {
69                dir = args[++i];
70            } else if (arg.equals("-db")) {
71                db = args[++i];
72            } else if (arg.equals("-quiet")) {
73                quiet = true;
74            } else if (arg.equals("-file")) {
75                zipFileName = args[++i];
76            } else if (arg.equals("-help") || arg.equals("-?")) {
77                showUsage();
78                return;
79            } else {
80                showUsageAndThrowUnsupportedOption(arg);
81            }
82        }
83        try {
84            process(zipFileName, dir, db, quiet);
85        } catch (Exception e) {
86            throw DbException.toSQLException(e);
87        }
88    }
89 
90    /**
91     * Backs up database files.
92     *
93     * @param zipFileName the name of the target backup file (including path)
94     * @param directory the source directory name
95     * @param db the source database name (null if there is only one database,
96     *            and and empty string to backup all files in this directory)
97     * @param quiet don't print progress information
98     */
99    public static void execute(String zipFileName, String directory, String db,
100            boolean quiet) throws SQLException {
101        try {
102            new Backup().process(zipFileName, directory, db, quiet);
103        } catch (Exception e) {
104            throw DbException.toSQLException(e);
105        }
106    }
107 
108    private void process(String zipFileName, String directory, String db,
109            boolean quiet) throws SQLException {
110        List<String> list;
111        boolean allFiles = db != null && db.length() == 0;
112        if (allFiles) {
113            list = FileUtils.newDirectoryStream(directory);
114        } else {
115            list = FileLister.getDatabaseFiles(directory, db, true);
116        }
117        if (list.size() == 0) {
118            if (!quiet) {
119                printNoDatabaseFilesFound(directory, db);
120            }
121            return;
122        }
123        if (!quiet) {
124            FileLister.tryUnlockDatabase(list, "backup");
125        }
126        zipFileName = FileUtils.toRealPath(zipFileName);
127        FileUtils.delete(zipFileName);
128        OutputStream fileOut = null;
129        try {
130            fileOut = FileUtils.newOutputStream(zipFileName, false);
131            ZipOutputStream zipOut = new ZipOutputStream(fileOut);
132            String base = "";
133            for (String fileName : list) {
134                if (allFiles ||
135                        fileName.endsWith(Constants.SUFFIX_PAGE_FILE) ||
136                        fileName.endsWith(Constants.SUFFIX_MV_FILE)) {
137                    base = FileUtils.getParent(fileName);
138                    break;
139                }
140            }
141            for (String fileName : list) {
142                String f = FileUtils.toRealPath(fileName);
143                if (!f.startsWith(base)) {
144                    DbException.throwInternalError(f + " does not start with " + base);
145                }
146                if (f.endsWith(zipFileName)) {
147                    continue;
148                }
149                if (FileUtils.isDirectory(fileName)) {
150                    continue;
151                }
152                f = f.substring(base.length());
153                f = BackupCommand.correctFileName(f);
154                ZipEntry entry = new ZipEntry(f);
155                zipOut.putNextEntry(entry);
156                InputStream in = null;
157                try {
158                    in = FileUtils.newInputStream(fileName);
159                    IOUtils.copyAndCloseInput(in, zipOut);
160                } catch (FileNotFoundException e) {
161                    // the file could have been deleted in the meantime
162                    // ignore this (in this case an empty file is created)
163                } finally {
164                    IOUtils.closeSilently(in);
165                }
166                zipOut.closeEntry();
167                if (!quiet) {
168                    out.println("Processed: " + fileName);
169                }
170            }
171            zipOut.close();
172        } catch (IOException e) {
173            throw DbException.convertIOException(e, zipFileName);
174        } finally {
175            IOUtils.closeSilently(fileOut);
176        }
177    }
178 
179}

[all classes][org.h2.tools]
EMMA 2.0.5312 (C) Vladimir Roubtsov