/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.samples;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.TimeUnit;
import org.h2.api.DatabaseEventListener;
import org.h2.jdbc.JdbcConnection;
/**
* This example application implements a database event listener. This is useful
* to display progress information while opening a large database, or to log
* database exceptions.
*/
public class ShowProgress implements DatabaseEventListener {
private final long startNs;
private long lastNs;
/**
* Create a new instance of this class, and startNs the timer.
*/
public ShowProgress() {
startNs = lastNs = System.nanoTime();
}
/**
* This method is called when executing this sample application from the
* command line.
*
* @param args the command line parameters
*/
public static void main(String... args) throws Exception {
new ShowProgress().test();
}
/**
* Run the progress test.
*/
void test() throws Exception {
Class.forName("org.h2.Driver");
Connection conn = DriverManager.getConnection("jdbc:h2:test", "sa", "");
Statement stat = conn.createStatement();
stat.execute("DROP TABLE IF EXISTS TEST");
stat.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR)");
PreparedStatement prep = conn.prepareStatement(
"INSERT INTO TEST VALUES(?, 'Test' || SPACE(100))");
long time;
time = System.nanoTime();
int len = 1000;
for (int i = 0; i < len; i++) {
long now = System.nanoTime();
if (now > time + TimeUnit.SECONDS.toNanos(1)) {
time = now;
System.out.println("Inserting " + (100L * i / len) + "%");
}
prep.setInt(1, i);
prep.execute();
}
boolean abnormalTermination = true;
if (abnormalTermination) {
((JdbcConnection) conn).setPowerOffCount(1);
try {
stat.execute("INSERT INTO TEST VALUES(-1, 'Test' || SPACE(100))");
} catch (SQLException e) {
// ignore
}
} else {
conn.close();
}
System.out.println("Open connection...");
time = System.nanoTime();
conn = DriverManager.getConnection(
"jdbc:h2:test;DATABASE_EVENT_LISTENER='" +
getClass().getName() + "'", "sa", "");
time = System.nanoTime() - time;
System.out.println("Done after " + TimeUnit.NANOSECONDS.toMillis(time) + " ms");
prep.close();
stat.close();
conn.close();
}
/**
* This method is called if an exception occurs in the database.
*
* @param e the exception
* @param sql the SQL statement
*/
@Override
public void exceptionThrown(SQLException e, String sql) {
System.out.println("Error executing " + sql);
e.printStackTrace();
}
/**
* This method is called when opening the database to notify about the
* progress.
*
* @param state the current state
* @param name the object name (depends on the state)
* @param current the current progress
* @param max the 100% mark
*/
@Override
public void setProgress(int state, String name, int current, int max) {
long time = System.nanoTime();
if (time < lastNs + TimeUnit.SECONDS.toNanos(5)) {
return;
}
lastNs = time;
String stateName = "?";
switch (state) {
case STATE_SCAN_FILE:
stateName = "Scan " + name;
break;
case STATE_CREATE_INDEX:
stateName = "Create Index " + name;
break;
case STATE_RECOVER:
stateName = "Recover";
break;
default:
return;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// ignore
}
System.out.println("State: " + stateName + " " +
(100 * current / max) + "% (" +
current + " of " + max + ") "
+ TimeUnit.NANOSECONDS.toMillis(time - startNs) + " ms");
}
/**
* This method is called when the database is closed.
*/
@Override
public void closingDatabase() {
System.out.println("Closing the database");
}
/**
* This method is called just after creating the instance.
*
* @param url the database URL
*/
@Override
public void init(String url) {
System.out.println("Initializing the event listener for database " + url);
}
/**
* This method is called when the database is open.
*/
@Override
public void opened() {
// do nothing
}
}