Search in sources :

Example 11 with Transfer

use of org.h2.value.Transfer in project h2database by h2database.

the class TcpServerThread method run.

@Override
public void run() {
    try {
        transfer.init();
        trace("Connect");
        // and a list of allowed clients
        try {
            Socket socket = transfer.getSocket();
            if (socket == null) {
                // the transfer is already closed, prevent NPE in TcpServer#allow(Socket)
                return;
            }
            if (!server.allow(transfer.getSocket())) {
                throw DbException.get(ErrorCode.REMOTE_CONNECTION_NOT_ALLOWED);
            }
            int minClientVersion = transfer.readInt();
            int maxClientVersion = transfer.readInt();
            if (maxClientVersion < Constants.TCP_PROTOCOL_VERSION_MIN_SUPPORTED) {
                throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_MIN_SUPPORTED);
            } else if (minClientVersion > Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED) {
                throw DbException.get(ErrorCode.DRIVER_VERSION_ERROR_2, "" + clientVersion, "" + Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED);
            }
            if (maxClientVersion >= Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED) {
                clientVersion = Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED;
            } else {
                clientVersion = maxClientVersion;
            }
            transfer.setVersion(clientVersion);
            String db = transfer.readString();
            String originalURL = transfer.readString();
            if (db == null && originalURL == null) {
                String targetSessionId = transfer.readString();
                int command = transfer.readInt();
                stop = true;
                if (command == SessionRemote.SESSION_CANCEL_STATEMENT) {
                    // cancel a running statement
                    int statementId = transfer.readInt();
                    server.cancelStatement(targetSessionId, statementId);
                } else if (command == SessionRemote.SESSION_CHECK_KEY) {
                    // check if this is the correct server
                    db = server.checkKeyAndGetDatabaseName(targetSessionId);
                    if (!targetSessionId.equals(db)) {
                        transfer.writeInt(SessionRemote.STATUS_OK);
                    } else {
                        transfer.writeInt(SessionRemote.STATUS_ERROR);
                    }
                }
            }
            String baseDir = server.getBaseDir();
            if (baseDir == null) {
                baseDir = SysProperties.getBaseDir();
            }
            db = server.checkKeyAndGetDatabaseName(db);
            ConnectionInfo ci = new ConnectionInfo(db);
            ci.setOriginalURL(originalURL);
            ci.setUserName(transfer.readString());
            ci.setUserPasswordHash(transfer.readBytes());
            ci.setFilePasswordHash(transfer.readBytes());
            int len = transfer.readInt();
            for (int i = 0; i < len; i++) {
                ci.setProperty(transfer.readString(), transfer.readString());
            }
            // override client's requested properties with server settings
            if (baseDir != null) {
                ci.setBaseDir(baseDir);
            }
            if (server.getIfExists()) {
                ci.setProperty("IFEXISTS", "TRUE");
            }
            transfer.writeInt(SessionRemote.STATUS_OK);
            transfer.writeInt(clientVersion);
            transfer.flush();
            if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_13) {
                if (ci.getFilePasswordHash() != null) {
                    ci.setFileEncryptionKey(transfer.readBytes());
                }
            }
            session = Engine.getInstance().createSession(ci);
            transfer.setSession(session);
            server.addConnection(threadId, originalURL, ci.getUserName());
            trace("Connected");
        } catch (Throwable e) {
            sendError(e);
            stop = true;
        }
        while (!stop) {
            try {
                process();
            } catch (Throwable e) {
                sendError(e);
            }
        }
        trace("Disconnect");
    } catch (Throwable e) {
        server.traceError(e);
    } finally {
        close();
    }
}
Also used : ConnectionInfo(org.h2.engine.ConnectionInfo) Socket(java.net.Socket)

Example 12 with Transfer

use of org.h2.value.Transfer in project h2database by h2database.

the class SessionRemote method initTransfer.

private Transfer initTransfer(ConnectionInfo ci, String db, String server) throws IOException {
    Socket socket = NetUtils.createSocket(server, Constants.DEFAULT_TCP_PORT, ci.isSSL());
    Transfer trans = new Transfer(this, socket);
    trans.setSSL(ci.isSSL());
    trans.init();
    trans.writeInt(Constants.TCP_PROTOCOL_VERSION_MIN_SUPPORTED);
    trans.writeInt(Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED);
    trans.writeString(db);
    trans.writeString(ci.getOriginalURL());
    trans.writeString(ci.getUserName());
    trans.writeBytes(ci.getUserPasswordHash());
    trans.writeBytes(ci.getFilePasswordHash());
    String[] keys = ci.getKeys();
    trans.writeInt(keys.length);
    for (String key : keys) {
        trans.writeString(key).writeString(ci.getProperty(key));
    }
    try {
        done(trans);
        clientVersion = trans.readInt();
        trans.setVersion(clientVersion);
        if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_14) {
            if (ci.getFileEncryptionKey() != null) {
                trans.writeBytes(ci.getFileEncryptionKey());
            }
        }
        trans.writeInt(SessionRemote.SESSION_SET_ID);
        trans.writeString(sessionId);
        done(trans);
        if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_15) {
            autoCommit = trans.readBoolean();
        } else {
            autoCommit = true;
        }
        return trans;
    } catch (DbException e) {
        trans.close();
        throw e;
    }
}
Also used : Transfer(org.h2.value.Transfer) Socket(java.net.Socket) DbException(org.h2.message.DbException)

Example 13 with Transfer

use of org.h2.value.Transfer in project h2database by h2database.

the class SessionRemote method hasPendingTransaction.

@Override
public boolean hasPendingTransaction() {
    if (clientVersion < Constants.TCP_PROTOCOL_VERSION_10) {
        return true;
    }
    for (int i = 0, count = 0; i < transferList.size(); i++) {
        Transfer transfer = transferList.get(i);
        try {
            traceOperation("SESSION_HAS_PENDING_TRANSACTION", 0);
            transfer.writeInt(SessionRemote.SESSION_HAS_PENDING_TRANSACTION);
            done(transfer);
            return transfer.readInt() != 0;
        } catch (IOException e) {
            removeServer(e, i--, ++count);
        }
    }
    return true;
}
Also used : Transfer(org.h2.value.Transfer) IOException(java.io.IOException)

Example 14 with Transfer

use of org.h2.value.Transfer in project h2database by h2database.

the class FileLock method checkServer.

private void checkServer() {
    Properties prop = load();
    String server = prop.getProperty("server");
    if (server == null) {
        return;
    }
    boolean running = false;
    String id = prop.getProperty("id");
    try {
        Socket socket = NetUtils.createSocket(server, Constants.DEFAULT_TCP_PORT, false);
        Transfer transfer = new Transfer(null, socket);
        transfer.init();
        transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_MIN_SUPPORTED);
        transfer.writeInt(Constants.TCP_PROTOCOL_VERSION_MAX_SUPPORTED);
        transfer.writeString(null);
        transfer.writeString(null);
        transfer.writeString(id);
        transfer.writeInt(SessionRemote.SESSION_CHECK_KEY);
        transfer.flush();
        int state = transfer.readInt();
        if (state == SessionRemote.STATUS_OK) {
            running = true;
        }
        transfer.close();
        socket.close();
    } catch (IOException e) {
        return;
    }
    if (running) {
        DbException e = DbException.get(ErrorCode.DATABASE_ALREADY_OPEN_1, "Server is running");
        throw e.addSQL(server + "/" + id);
    }
}
Also used : Transfer(org.h2.value.Transfer) IOException(java.io.IOException) SortedProperties(org.h2.util.SortedProperties) Properties(java.util.Properties) Socket(java.net.Socket) ServerSocket(java.net.ServerSocket) DbException(org.h2.message.DbException)

Example 15 with Transfer

use of org.h2.value.Transfer in project h2database by h2database.

the class Table method removeIndexOrTransferOwnership.

/**
 * If the index is still required by a constraint, transfer the ownership to
 * it. Otherwise, the index is removed.
 *
 * @param session the session
 * @param index the index that is no longer required
 */
public void removeIndexOrTransferOwnership(Session session, Index index) {
    boolean stillNeeded = false;
    if (constraints != null) {
        for (Constraint cons : constraints) {
            if (cons.usesIndex(index)) {
                cons.setIndexOwner(index);
                database.updateMeta(session, cons);
                stillNeeded = true;
            }
        }
    }
    if (!stillNeeded) {
        database.removeSchemaObject(session, index);
    }
}
Also used : Constraint(org.h2.constraint.Constraint)

Aggregations

IOException (java.io.IOException)15 Transfer (org.h2.value.Transfer)14 DbException (org.h2.message.DbException)5 Socket (java.net.Socket)3 ResultRemote (org.h2.result.ResultRemote)3 Value (org.h2.value.Value)3 Properties (java.util.Properties)2 ParameterInterface (org.h2.expression.ParameterInterface)2 JdbcSQLException (org.h2.jdbc.JdbcSQLException)2 ServerSocket (java.net.ServerSocket)1 Iterator (java.util.Iterator)1 Constraint (org.h2.constraint.Constraint)1 ConnectionInfo (org.h2.engine.ConnectionInfo)1 SysProperties (org.h2.engine.SysProperties)1 ParameterRemote (org.h2.expression.ParameterRemote)1 TraceSystem (org.h2.message.TraceSystem)1 SortedProperties (org.h2.util.SortedProperties)1