Search in sources :

Example 1 with DatabaseEventListener

use of org.h2.api.DatabaseEventListener in project h2database by h2database.

the class SessionRemote method connectServer.

private void connectServer(ConnectionInfo ci) {
    String name = ci.getName();
    if (name.startsWith("//")) {
        name = name.substring("//".length());
    }
    int idx = name.indexOf('/');
    if (idx < 0) {
        throw ci.getFormatException();
    }
    databaseName = name.substring(idx + 1);
    String server = name.substring(0, idx);
    traceSystem = new TraceSystem(null);
    String traceLevelFile = ci.getProperty(SetTypes.TRACE_LEVEL_FILE, null);
    if (traceLevelFile != null) {
        int level = Integer.parseInt(traceLevelFile);
        String prefix = getFilePrefix(SysProperties.CLIENT_TRACE_DIRECTORY);
        try {
            traceSystem.setLevelFile(level);
            if (level > 0 && level < 4) {
                String file = FileUtils.createTempFile(prefix, Constants.SUFFIX_TRACE_FILE, false, false);
                traceSystem.setFileName(file);
            }
        } catch (IOException e) {
            throw DbException.convertIOException(e, prefix);
        }
    }
    String traceLevelSystemOut = ci.getProperty(SetTypes.TRACE_LEVEL_SYSTEM_OUT, null);
    if (traceLevelSystemOut != null) {
        int level = Integer.parseInt(traceLevelSystemOut);
        traceSystem.setLevelSystemOut(level);
    }
    trace = traceSystem.getTrace(Trace.JDBC);
    String serverList = null;
    if (server.indexOf(',') >= 0) {
        serverList = StringUtils.quoteStringSQL(server);
        ci.setProperty("CLUSTER", Constants.CLUSTERING_ENABLED);
    }
    autoReconnect = ci.getProperty("AUTO_RECONNECT", false);
    // AUTO_SERVER implies AUTO_RECONNECT
    boolean autoServer = ci.getProperty("AUTO_SERVER", false);
    if (autoServer && serverList != null) {
        throw DbException.getUnsupportedException("autoServer && serverList != null");
    }
    autoReconnect |= autoServer;
    if (autoReconnect) {
        String className = ci.getProperty("DATABASE_EVENT_LISTENER");
        if (className != null) {
            className = StringUtils.trim(className, true, true, "'");
            try {
                eventListener = (DatabaseEventListener) JdbcUtils.loadUserClass(className).newInstance();
            } catch (Throwable e) {
                throw DbException.convert(e);
            }
        }
    }
    cipher = ci.getProperty("CIPHER");
    if (cipher != null) {
        fileEncryptionKey = MathUtils.secureRandomBytes(32);
    }
    String[] servers = StringUtils.arraySplit(server, ',', true);
    int len = servers.length;
    transferList.clear();
    sessionId = StringUtils.convertBytesToHex(MathUtils.secureRandomBytes(32));
    // TODO cluster: support more than 2 connections
    boolean switchOffCluster = false;
    try {
        for (String s : servers) {
            try {
                Transfer trans = initTransfer(ci, databaseName, s);
                transferList.add(trans);
            } catch (IOException e) {
                if (len == 1) {
                    throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, e, e + ": " + s);
                }
                switchOffCluster = true;
            }
        }
        checkClosed();
        if (switchOffCluster) {
            switchOffCluster();
        }
        checkClusterDisableAutoCommit(serverList);
    } catch (DbException e) {
        traceSystem.close();
        throw e;
    }
}
Also used : Transfer(org.h2.value.Transfer) IOException(java.io.IOException) TraceSystem(org.h2.message.TraceSystem) DbException(org.h2.message.DbException)

Example 2 with DatabaseEventListener

use of org.h2.api.DatabaseEventListener in project h2database by h2database.

the class Database method close.

/**
 * Close the database.
 *
 * @param fromShutdownHook true if this method is called from the shutdown
 *            hook
 */
void close(boolean fromShutdownHook) {
    try {
        synchronized (this) {
            if (closing) {
                return;
            }
            throwLastBackgroundException();
            if (fileLockMethod == FileLockMethod.SERIALIZED && !reconnectChangePending) {
                // another connection may have written something - don't write
                try {
                    closeOpenFilesAndUnlock(false);
                } catch (DbException e) {
                // ignore
                }
                traceSystem.close();
                return;
            }
            closing = true;
            stopServer();
            if (!userSessions.isEmpty()) {
                if (!fromShutdownHook) {
                    return;
                }
                trace.info("closing {0} from shutdown hook", databaseName);
                closeAllSessionsException(null);
            }
            trace.info("closing {0}", databaseName);
            if (eventListener != null) {
                // allow the event listener to connect to the database
                closing = false;
                DatabaseEventListener e = eventListener;
                // set it to null, to make sure it's called only once
                eventListener = null;
                e.closingDatabase();
                if (!userSessions.isEmpty()) {
                    // if a connection was opened, we can't close the database
                    return;
                }
                closing = true;
            }
        }
        if (!this.isReadOnly()) {
            removeOrphanedLobs();
        }
        try {
            if (systemSession != null) {
                if (powerOffCount != -1) {
                    for (Table table : getAllTablesAndViews(false)) {
                        if (table.isGlobalTemporary()) {
                            table.removeChildrenAndResources(systemSession);
                        } else {
                            table.close(systemSession);
                        }
                    }
                    for (SchemaObject obj : getAllSchemaObjects(DbObject.SEQUENCE)) {
                        Sequence sequence = (Sequence) obj;
                        sequence.close();
                    }
                }
                for (SchemaObject obj : getAllSchemaObjects(DbObject.TRIGGER)) {
                    TriggerObject trigger = (TriggerObject) obj;
                    try {
                        trigger.close();
                    } catch (SQLException e) {
                        trace.error(e, "close");
                    }
                }
                if (powerOffCount != -1) {
                    meta.close(systemSession);
                    systemSession.commit(true);
                }
            }
        } catch (DbException e) {
            trace.error(e, "close");
        }
        tempFileDeleter.deleteAll();
        try {
            closeOpenFilesAndUnlock(true);
        } catch (DbException e) {
            trace.error(e, "close");
        }
        trace.info("closed");
        traceSystem.close();
        if (closeOnExit != null) {
            closeOnExit.reset();
            try {
                Runtime.getRuntime().removeShutdownHook(closeOnExit);
            } catch (IllegalStateException e) {
            // ignore
            } catch (SecurityException e) {
            // applets may not do that - ignore
            }
            closeOnExit = null;
        }
        if (deleteFilesOnDisconnect && persistent) {
            deleteFilesOnDisconnect = false;
            try {
                String directory = FileUtils.getParent(databaseName);
                String name = FileUtils.getName(databaseName);
                DeleteDbFiles.execute(directory, name, true);
            } catch (Exception e) {
            // ignore (the trace is closed already)
            }
        }
    } finally {
        Engine.getInstance().close(databaseName);
    }
}
Also used : SchemaObject(org.h2.schema.SchemaObject) DatabaseEventListener(org.h2.api.DatabaseEventListener) MetaTable(org.h2.table.MetaTable) Table(org.h2.table.Table) SQLException(java.sql.SQLException) TriggerObject(org.h2.schema.TriggerObject) Sequence(org.h2.schema.Sequence) DbException(org.h2.message.DbException) SQLException(java.sql.SQLException) IOException(java.io.IOException) DbException(org.h2.message.DbException)

Example 3 with DatabaseEventListener

use of org.h2.api.DatabaseEventListener in project h2database by h2database.

the class MetaRecord method execute.

/**
 * Execute the meta data statement.
 *
 * @param db the database
 * @param systemSession the system session
 * @param listener the database event listener
 */
void execute(Database db, Session systemSession, DatabaseEventListener listener) {
    try {
        Prepared command = systemSession.prepare(sql);
        command.setObjectId(id);
        command.update();
    } catch (DbException e) {
        e = e.addSQL(sql);
        SQLException s = e.getSQLException();
        db.getTrace(Trace.DATABASE).error(s, sql);
        if (listener != null) {
            listener.exceptionThrown(s, sql);
        // continue startup in this case
        } else {
            throw e;
        }
    }
}
Also used : SQLException(java.sql.SQLException) Prepared(org.h2.command.Prepared) DbException(org.h2.message.DbException)

Aggregations

DbException (org.h2.message.DbException)3 IOException (java.io.IOException)2 SQLException (java.sql.SQLException)2 DatabaseEventListener (org.h2.api.DatabaseEventListener)1 Prepared (org.h2.command.Prepared)1 TraceSystem (org.h2.message.TraceSystem)1 SchemaObject (org.h2.schema.SchemaObject)1 Sequence (org.h2.schema.Sequence)1 TriggerObject (org.h2.schema.TriggerObject)1 MetaTable (org.h2.table.MetaTable)1 Table (org.h2.table.Table)1 Transfer (org.h2.value.Transfer)1