Search in sources :

Example 1 with ErrorCode

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

the class Command method filterConcurrentUpdate.

private long filterConcurrentUpdate(DbException e, long start) {
    int errorCode = e.getErrorCode();
    if (errorCode != ErrorCode.CONCURRENT_UPDATE_1 && errorCode != ErrorCode.ROW_NOT_FOUND_IN_PRIMARY_INDEX && errorCode != ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1) {
        throw e;
    }
    long now = System.nanoTime() / 1_000_000;
    if (start != 0 && now - start > session.getLockTimeout()) {
        throw DbException.get(ErrorCode.LOCK_TIMEOUT_1, e.getCause(), "");
    }
    Database database = session.getDatabase();
    int sleep = 1 + MathUtils.randomInt(10);
    while (true) {
        try {
            if (database.isMultiThreaded()) {
                Thread.sleep(sleep);
            } else {
                database.wait(sleep);
            }
        } catch (InterruptedException e1) {
        // ignore
        }
        long slept = System.nanoTime() / 1_000_000 - now;
        if (slept >= sleep) {
            break;
        }
    }
    return start == 0 ? now : start;
}
Also used : Database(org.h2.engine.Database)

Example 2 with ErrorCode

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

the class SetComment method update.

@Override
public int update() {
    session.commit(true);
    Database db = session.getDatabase();
    session.getUser().checkAdmin();
    DbObject object = null;
    int errorCode = ErrorCode.GENERAL_ERROR_1;
    if (schemaName == null) {
        schemaName = session.getCurrentSchemaName();
    }
    switch(objectType) {
        case DbObject.CONSTANT:
            object = db.getSchema(schemaName).getConstant(objectName);
            break;
        case DbObject.CONSTRAINT:
            object = db.getSchema(schemaName).getConstraint(objectName);
            break;
        case DbObject.FUNCTION_ALIAS:
            object = db.getSchema(schemaName).findFunction(objectName);
            errorCode = ErrorCode.FUNCTION_ALIAS_NOT_FOUND_1;
            break;
        case DbObject.INDEX:
            object = db.getSchema(schemaName).getIndex(objectName);
            break;
        case DbObject.ROLE:
            schemaName = null;
            object = db.findRole(objectName);
            errorCode = ErrorCode.ROLE_NOT_FOUND_1;
            break;
        case DbObject.SCHEMA:
            schemaName = null;
            object = db.findSchema(objectName);
            errorCode = ErrorCode.SCHEMA_NOT_FOUND_1;
            break;
        case DbObject.SEQUENCE:
            object = db.getSchema(schemaName).getSequence(objectName);
            break;
        case DbObject.TABLE_OR_VIEW:
            object = db.getSchema(schemaName).getTableOrView(session, objectName);
            break;
        case DbObject.TRIGGER:
            object = db.getSchema(schemaName).findTrigger(objectName);
            errorCode = ErrorCode.TRIGGER_NOT_FOUND_1;
            break;
        case DbObject.USER:
            schemaName = null;
            object = db.getUser(objectName);
            break;
        case DbObject.USER_DATATYPE:
            schemaName = null;
            object = db.findUserDataType(objectName);
            errorCode = ErrorCode.USER_DATA_TYPE_ALREADY_EXISTS_1;
            break;
        default:
    }
    if (object == null) {
        throw DbException.get(errorCode, objectName);
    }
    String text = expr.optimize(session).getValue(session).getString();
    if (column) {
        Table table = (Table) object;
        table.getColumn(columnName).setComment(text);
    } else {
        object.setComment(text);
    }
    if (column || objectType == DbObject.TABLE_OR_VIEW || objectType == DbObject.USER || objectType == DbObject.INDEX || objectType == DbObject.CONSTRAINT) {
        db.updateMeta(session, object);
    } else {
        Comment comment = db.findComment(object);
        if (comment == null) {
            if (text == null) {
            // reset a non-existing comment - nothing to do
            } else {
                int id = getObjectId();
                comment = new Comment(db, id, object);
                comment.setCommentText(text);
                db.addDatabaseObject(session, comment);
            }
        } else {
            if (text == null) {
                db.removeDatabaseObject(session, comment);
            } else {
                comment.setCommentText(text);
                db.updateMeta(session, comment);
            }
        }
    }
    return 0;
}
Also used : Comment(org.h2.engine.Comment) Table(org.h2.table.Table) DbObject(org.h2.engine.DbObject) Database(org.h2.engine.Database)

Example 3 with ErrorCode

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

the class SessionRemote method done.

/**
 * Called to flush the output after data has been sent to the server and
 * just before receiving data. This method also reads the status code from
 * the server and throws any exception the server sent.
 *
 * @param transfer the transfer object
 * @throws DbException if the server sent an exception
 * @throws IOException if there is a communication problem between client
 *             and server
 */
public void done(Transfer transfer) throws IOException {
    transfer.flush();
    int status = transfer.readInt();
    if (status == STATUS_ERROR) {
        String sqlstate = transfer.readString();
        String message = transfer.readString();
        String sql = transfer.readString();
        int errorCode = transfer.readInt();
        String stackTrace = transfer.readString();
        JdbcSQLException s = new JdbcSQLException(message, sql, sqlstate, errorCode, null, stackTrace);
        if (errorCode == ErrorCode.CONNECTION_BROKEN_1) {
            // allow re-connect
            throw new IOException(s.toString(), s);
        }
        throw DbException.convert(s);
    } else if (status == STATUS_CLOSED) {
        transferList = null;
    } else if (status == STATUS_OK_STATE_CHANGED) {
        sessionStateChanged = true;
    } else if (status == STATUS_OK) {
    // ok
    } else {
        throw DbException.get(ErrorCode.CONNECTION_BROKEN_1, "unexpected status " + status);
    }
}
Also used : JdbcSQLException(org.h2.jdbc.JdbcSQLException) IOException(java.io.IOException)

Example 4 with ErrorCode

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

the class TestReopen method logDb.

private synchronized void logDb(String fileName) {
    writeCount++;
    if ((writeCount & (testEvery - 1)) != 0) {
        return;
    }
    if (FileUtils.size(fileName) > maxFileSize) {
        // System.out.println(fileName + " " + IOUtils.length(fileName));
        return;
    }
    System.out.println("+ write #" + writeCount + " verify #" + verifyCount);
    try {
        if (fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) {
            IOUtils.copyFiles(fileName, testDatabase + Constants.SUFFIX_PAGE_FILE);
        } else {
            IOUtils.copyFiles(fileName, testDatabase + Constants.SUFFIX_MV_FILE);
        }
        verifyCount++;
        // avoid using the Engine class to avoid deadlocks
        Properties p = new Properties();
        String userName = getUser();
        p.setProperty("user", userName);
        p.setProperty("password", getPassword());
        String url = "jdbc:h2:" + testDatabase + ";FILE_LOCK=NO;TRACE_LEVEL_FILE=0";
        ConnectionInfo ci = new ConnectionInfo(url, p);
        Database database = new Database(ci, null);
        // close the database
        Session session = database.getSystemSession();
        session.prepare("script to '" + testDatabase + ".sql'").query(0);
        session.prepare("shutdown immediately").update();
        database.removeSession(null);
        // everything OK - return
        return;
    } catch (DbException e) {
        SQLException e2 = DbException.toSQLException(e);
        int errorCode = e2.getErrorCode();
        if (errorCode == ErrorCode.WRONG_USER_OR_PASSWORD) {
            return;
        } else if (errorCode == ErrorCode.FILE_ENCRYPTION_ERROR_1) {
            return;
        }
        e.printStackTrace(System.out);
        throw e;
    } catch (Exception e) {
        // failed
        int errorCode = 0;
        if (e instanceof SQLException) {
            errorCode = ((SQLException) e).getErrorCode();
        }
        if (errorCode == ErrorCode.WRONG_USER_OR_PASSWORD) {
            return;
        } else if (errorCode == ErrorCode.FILE_ENCRYPTION_ERROR_1) {
            return;
        }
        e.printStackTrace(System.out);
    }
    System.out.println("begin ------------------------------ " + writeCount);
    try {
        Recover.execute(fileName.substring(0, fileName.lastIndexOf('/')), null);
    } catch (SQLException e) {
    // ignore
    }
    testDatabase += "X";
    try {
        if (fileName.endsWith(Constants.SUFFIX_PAGE_FILE)) {
            IOUtils.copyFiles(fileName, testDatabase + Constants.SUFFIX_PAGE_FILE);
        } else {
            IOUtils.copyFiles(fileName, testDatabase + Constants.SUFFIX_MV_FILE);
        }
        // avoid using the Engine class to avoid deadlocks
        Properties p = new Properties();
        String url = "jdbc:h2:" + testDatabase + ";FILE_LOCK=NO";
        ConnectionInfo ci = new ConnectionInfo(url, p);
        Database database = new Database(ci, null);
        // close the database
        database.removeSession(null);
    } catch (Exception e) {
        int errorCode = 0;
        if (e instanceof DbException) {
            e = ((DbException) e).getSQLException();
            errorCode = ((SQLException) e).getErrorCode();
        }
        if (errorCode == ErrorCode.WRONG_USER_OR_PASSWORD) {
            return;
        } else if (errorCode == ErrorCode.FILE_ENCRYPTION_ERROR_1) {
            return;
        }
        StringBuilder buff = new StringBuilder();
        StackTraceElement[] list = e.getStackTrace();
        for (int i = 0; i < 10 && i < list.length; i++) {
            buff.append(list[i].toString()).append('\n');
        }
        String s = buff.toString();
        if (!knownErrors.contains(s)) {
            System.out.println(writeCount + " code: " + errorCode + " " + e.toString());
            e.printStackTrace(System.out);
            knownErrors.add(s);
        } else {
            System.out.println(writeCount + " code: " + errorCode);
        }
    }
}
Also used : SQLException(java.sql.SQLException) Database(org.h2.engine.Database) ConnectionInfo(org.h2.engine.ConnectionInfo) Properties(java.util.Properties) DbException(org.h2.message.DbException) SQLException(java.sql.SQLException) Session(org.h2.engine.Session) DbException(org.h2.message.DbException)

Example 5 with ErrorCode

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

the class TestMvccMultiThreaded method testConcurrentSelectForUpdate.

private void testConcurrentSelectForUpdate() throws Exception {
    deleteDb(getTestName());
    Connection conn = getConnection(getTestName() + ";MULTI_THREADED=TRUE");
    Statement stat = conn.createStatement();
    stat.execute("create table test(id int not null primary key, updated int not null)");
    stat.execute("insert into test(id, updated) values(1, 100)");
    ArrayList<Task> tasks = new ArrayList<>();
    int count = 3;
    for (int i = 0; i < count; i++) {
        Task task = new Task() {

            @Override
            public void call() throws Exception {
                Connection conn = getConnection(getTestName());
                Statement stat = conn.createStatement();
                try {
                    while (!stop) {
                        try {
                            stat.execute("select * from test where id=1 for update");
                        } catch (SQLException e) {
                            int errorCode = e.getErrorCode();
                            assertTrue(e.getMessage(), errorCode == ErrorCode.DEADLOCK_1 || errorCode == ErrorCode.LOCK_TIMEOUT_1);
                        }
                    }
                } finally {
                    conn.close();
                }
            }
        }.execute();
        tasks.add(task);
    }
    for (int i = 0; i < 10; i++) {
        Thread.sleep(100);
        ResultSet rs = stat.executeQuery("select * from test");
        assertTrue(rs.next());
    }
    for (Task t : tasks) {
        t.get();
    }
    conn.close();
    deleteDb(getTestName());
}
Also used : Task(org.h2.util.Task) SQLException(java.sql.SQLException) Statement(java.sql.Statement) Connection(java.sql.Connection) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet) SQLException(java.sql.SQLException)

Aggregations

Database (org.h2.engine.Database)4 SQLException (java.sql.SQLException)3 IOException (java.io.IOException)2 Properties (java.util.Properties)2 ConnectionInfo (org.h2.engine.ConnectionInfo)2 Session (org.h2.engine.Session)2 DbException (org.h2.message.DbException)2 Connection (java.sql.Connection)1 ResultSet (java.sql.ResultSet)1 Statement (java.sql.Statement)1 ArrayList (java.util.ArrayList)1 Comment (org.h2.engine.Comment)1 DbObject (org.h2.engine.DbObject)1 JdbcSQLException (org.h2.jdbc.JdbcSQLException)1 Table (org.h2.table.Table)1 Task (org.h2.util.Task)1