Mercurial > hg > monetdb-java
view src/main/java/nl/cwi/monetdb/util/SQLRestore.java @ 64:bb0d66ad7dc6 embedded
More done
author | Pedro Ferreira <pedro.ferreira@monetdbsolutions.com> |
---|---|
date | Thu, 01 Dec 2016 16:52:27 +0100 (2016-12-01) |
parents | 6325594f01af |
children | 87ba760038b6 |
line wrap: on
line source
/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V. */ package nl.cwi.monetdb.util; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; import nl.cwi.monetdb.mcl.connection.MCLException; import nl.cwi.monetdb.mcl.io.AbstractMCLReader; import nl.cwi.monetdb.mcl.io.AbstractMCLWriter; import nl.cwi.monetdb.mcl.connection.DeleteMe; import nl.cwi.monetdb.mcl.parser.MCLParseException; /** * Use this class to restore an SQL dump file. */ public class SQLRestore { private final String _host; private final int _port; private final String _user; private final String _password; private final String _dbName; public SQLRestore(String host, int port, String user, String password, String dbName) throws IOException { if (host == null || user == null || password == null || dbName == null) throw new NullPointerException(); _host = host; _port = port; _user = user; _password = password; _dbName = dbName; } private static class ServerResponseReader implements Runnable { private final AbstractMCLReader _is; private final AtomicBoolean _errorState = new AtomicBoolean(false); private String _errorMessage = null; ServerResponseReader(AbstractMCLReader is) { _is = is; } public void run() { try { while (true) { String line = _is.readLine(); if (line == null) break; int result = _is.getLineType(); switch (result) { case AbstractMCLReader.ERROR: _errorMessage = line; _errorState.set(true); return; default: // do nothing... } } } catch (IOException e) { _errorMessage = e.getMessage(); _errorState.set(true); } finally { try { _is.close(); } catch (IOException e) { // ignore errors } } } /** * @return whether the server has responded with an error. Any * error is regarded as fatal. */ public boolean inErrorState() { return _errorState.get(); } /** * @return the error message if inErrorState() is true. Behaviour is * not defined if called before inErrorState is true. */ public String getErrorMessage() { return _errorMessage; } } /** * Restores a given SQL dump to the database. * * @param source File location of the SQL dump * @throws IOException */ public void restore(File source) throws IOException { DeleteMe ms = new DeleteMe(_host, _port, _dbName, _user, false, "sql", "SHA256"); try { ms.connect(_user, _password); AbstractMCLWriter os = ms.getWriter(); AbstractMCLReader reader = ms.getReader(); ServerResponseReader srr = new ServerResponseReader(reader); Thread responseReaderThread = new Thread(srr); responseReaderThread.start(); try { // FIXME: we assume here that the dump is in system's default encoding BufferedReader sourceData = new BufferedReader(new FileReader(source)); try { os.write('s'); // signal that a new statement (or series of) is coming while(!srr.inErrorState()) { char[] buf = new char[4096]; int result = sourceData.read(buf); if (result < 0) break; os.write(buf, 0, result); } os.flush(); // mark the end of the statement (or series of) os.close(); } finally { sourceData.close(); } } finally { try { responseReaderThread.join(); } catch (InterruptedException e) { throw new IOException(e.getMessage()); } // if the server signalled an error, we should respect it... if (srr.inErrorState()) { throw new IOException(srr.getErrorMessage()); } } } catch (MCLException | MCLParseException e) { throw new IOException(e.getMessage()); } finally { ms.close(); } } public void close() { // do nothing at the moment... } public static void main(String[] args) throws IOException { if (args.length != 6) { System.err.println("USAGE: java " + SQLRestore.class.getName() + " <host> <port> <user> <password> <dbname> <dumpfile>"); System.exit(1); } // parse arguments String host = args[0]; int port = Integer.parseInt(args[1]); // FIXME: catch NumberFormatException String user = args[2]; String password = args[3]; String dbName = args[4]; File dumpFile = new File(args[5]); // check arguments if (!dumpFile.isFile() || !dumpFile.canRead()) { System.err.println("Cannot read: " + dumpFile); System.exit(1); } SQLRestore md = new SQLRestore(host, port, user, password, dbName); try { System.out.println("Start restoring " + dumpFile); long duration = -System.currentTimeMillis(); md.restore(dumpFile); duration += System.currentTimeMillis(); System.out.println("Restoring took: " + duration + "ms"); } finally { md.close(); } } }