com.tesora.dve.sql.util.ProxyConnectionResource.java Source code

Java tutorial

Introduction

Here is the source code for com.tesora.dve.sql.util.ProxyConnectionResource.java

Source

package com.tesora.dve.sql.util;

/*
 * #%L
 * Tesora Inc.
 * Database Virtualization Engine
 * %%
 * Copyright (C) 2011 - 2014 Tesora Inc.
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */

import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;

import com.tesora.dve.server.global.HostService;
import com.tesora.dve.singleton.Singletons;
import org.apache.commons.lang.StringUtils;

import com.tesora.dve.common.DBHelper;
import com.tesora.dve.comms.client.messages.DisconnectRequest;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.server.connectionmanager.SSConnection;
import com.tesora.dve.server.connectionmanager.messages.ExecuteRequestExecutor;
import com.tesora.dve.sql.SchemaException;
import com.tesora.dve.sql.SchemaTest;
import com.tesora.dve.sql.parser.ParserInvoker.LineInfo;
import com.tesora.dve.worker.DBConnectionParameters;
import com.tesora.dve.worker.MysqlTextResultChunkProvider;
import com.tesora.dve.worker.UserCredentials;

public class ProxyConnectionResource extends ConnectionResource {

    private DBConnectionParameters connectionParams;
    private SSConnection proxy;

    private String userName = null;
    private String password = null;

    private boolean lastHadWarning = false;

    public ProxyConnectionResource() throws Throwable {
        this(null, null);
    }

    public ProxyConnectionResource(String userName, String password) throws Throwable {
        super(null);
        this.userName = userName;
        this.password = password;
        Properties props = (Properties) Singletons.require(HostService.class).getProperties().clone();
        if (userName != null)
            props.setProperty(DBHelper.CONN_USER, userName);
        if (password != null)
            props.setProperty(DBHelper.CONN_PASSWORD, password);
        connectionParams = new DBConnectionParameters(props);
        proxy = null;
        connect();
    }

    protected ProxyConnectionResource(ProxyConnectionResource pcr) throws Throwable {
        super(pcr);
        this.userName = pcr.userName;
        this.password = pcr.password;
        this.connectionParams = new DBConnectionParameters(pcr.connectionParams);
        this.proxy = null;
        connect();
    }

    @Override
    public void connect() throws Throwable {
        if (proxy != null)
            return;
        proxy = new SSConnection();
        try {
            proxy.startConnection(
                    new UserCredentials(connectionParams.getUserid(), connectionParams.getPassword()));
            executePostConnectCmds();
        } catch (Throwable t) {
            proxy.close();
            throw t;
        }

    }

    @Override
    public void disconnect() throws Throwable {
        if (proxy == null)
            return;

        DisconnectRequest discon = new DisconnectRequest();
        proxy.executeMessageDirect(discon);
        proxy.close();
        proxy = null;
    }

    public ResourceResponse execute(LineInfo info, final byte[] stmt) throws Throwable {
        if (info != null)
            SchemaTest.echo("Executing@" + info + ": '" + stmt + "'");
        else
            SchemaTest.echo("Executing: '" + stmt + "'");

        //      final NativeCharSet clientCharSet = MysqlNativeCharSet.UTF8;
        final MysqlTextResultChunkProvider results = new MysqlTextResultChunkProvider();
        proxy.executeInContext(new Callable<Void>() {
            @SuppressWarnings("synthetic-access")
            @Override
            public Void call() throws Exception {
                try {
                    ExecuteRequestExecutor.execute(proxy, results, stmt);
                } catch (PEException e) {
                    throw e;
                } catch (SchemaException se) {
                    throw se;
                } catch (Throwable e) {
                    throw new PEException("Test statement encountered exception", e);
                }
                return null;
            }
        });

        lastHadWarning = results.getWarnings() > 0;

        return new ProxyConnectionResourceResponse(results);
    }

    @Override
    public ResourceResponse execute(LineInfo info, String stmt) throws Throwable {
        if (info != null)
            SchemaTest.echo("Executing@" + info + ": '" + stmt + "'");
        else
            SchemaTest.echo("Executing: '" + stmt + "'");

        return execute(info, stmt.getBytes());
    }

    @Override
    public ResourceResponse fetch(LineInfo info, String stmt) throws Throwable {
        return execute(info, stmt);
    }

    @Override
    public ExceptionClassification classifyException(Throwable t) {
        if (t.getMessage() == null)
            return null;

        String msg = t.getMessage().trim();
        if (StringUtils.containsIgnoreCase(msg, "No such Table:")
                || StringUtils.containsIgnoreCase(msg, "No such Column:"))
            return ExceptionClassification.DNE;
        if (StringUtils.containsIgnoreCase(msg, "No value found for required")
                && StringUtils.endsWithIgnoreCase(msg, "and no default specified"))
            return ExceptionClassification.DNE;
        if (StringUtils.containsIgnoreCase(msg, "Unsupported statement kind for planning:")
                && StringUtils.endsWithIgnoreCase(msg, "RollbackTransactionStatement"))
            return ExceptionClassification.DNE;
        if (StringUtils.containsIgnoreCase(msg, "Data Truncation:"))
            return ExceptionClassification.OUT_OF_RANGE;
        if (StringUtils.containsIgnoreCase(msg, "Unable to parse")
                || StringUtils.containsIgnoreCase(msg, "Unable to build plan")
                || StringUtils.containsIgnoreCase(msg, "Parsing FAILED:"))
            return ExceptionClassification.SYNTAX;
        if (StringUtils.containsIgnoreCase(msg, "Duplicate entry"))
            return ExceptionClassification.DUPLICATE;
        if (StringUtils.containsIgnoreCase(msg, "option not supported"))
            return ExceptionClassification.UNSUPPORTED_OPERATION;
        return null;
    }

    @Override
    public ConnectionResource getNewConnection() throws Throwable {
        return new ProxyConnectionResource(this);
    }

    @Override
    public boolean isConnected() throws Throwable {
        return proxy != null;
    }

    @Override
    public String describe() {
        if (userName == null && password == null)
            return "null/null";
        return userName + "/" + password;
    }

    @Override
    public Object prepare(LineInfo info, String stmt) throws Throwable {
        throw new PEException("prepare() method not implemented for ProxyConnectionResource");
    }

    @Override
    public ResourceResponse executePrepared(Object ps, List<Object> parameters) throws Throwable {
        throw new PEException("executePrepared() method not implemented for ProxyConnectionResource");
    }

    @Override
    public void destroyPrepared(Object ps) throws Throwable {
        throw new PEException("destroyPrepared() method not implemented for ProxyConnectionResource");
    }

    @Override
    public boolean hasWarnings() {
        return lastHadWarning;
    }

    public SSConnection getBackingConnection() {
        return proxy;
    }

}