com.alibaba.wasp.jdbc.command.CommandRemote.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.wasp.jdbc.command.CommandRemote.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.wasp.jdbc.command;

import com.alibaba.wasp.ReadModel;
import com.alibaba.wasp.SQLErrorCode;
import com.alibaba.wasp.client.FClient;
import com.alibaba.wasp.jdbc.JdbcException;
import com.alibaba.wasp.jdbc.expression.ParameterInterface;
import com.alibaba.wasp.jdbc.result.ResultInterface;
import com.alibaba.wasp.jdbc.result.ResultRemote;
import com.alibaba.wasp.jdbc.result.ResultTransfer;
import com.alibaba.wasp.jdbc.value.Value;
import com.alibaba.wasp.jdbc.value.ValueInt;
import com.alibaba.wasp.meta.Field;
import com.alibaba.wasp.session.ConnectionSession;
import com.alibaba.wasp.session.ExecuteSession;
import com.alibaba.wasp.session.SessionFactory;
import com.alibaba.wasp.util.New;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Represents the client-side part of a SQL statement. This class is not used in
 * embedded mode.
 */
public class CommandRemote implements CommandInterface {

    private Log log = LogFactory.getLog(CommandRemote.class);

    private final ArrayList<ParameterInterface> parameters;
    private final String sql;
    private final int fetchSize;
    private ConnectionSession session;
    private final FClient fClient;
    private int id;
    private boolean isQuery;
    private final int created;
    private final ReadModel readModel;
    private final boolean autoCommit;
    private ExecuteSession statementSession;
    private final List<String> sqls;

    public CommandRemote(FClient fClient, ConnectionSession session, String sql, int fetchSize, ReadModel readModel,
            boolean autoCommit, ExecuteSession statementSession, List<String> sqls) {
        this.sql = sql;
        parameters = New.arrayList();
        prepare(session, true);
        // set session late because prepare might fail - in this case we don't
        // need to close the object
        this.session = session;
        this.fClient = fClient;
        this.fetchSize = fetchSize;
        this.readModel = readModel;
        this.autoCommit = autoCommit;
        this.statementSession = statementSession;
        this.sqls = sqls;
        created = session.getLastReconnect();
    }

    public CommandRemote(FClient fClient, ConnectionSession session, List<String> sqls, boolean autoCommit,
            ExecuteSession statementSession) {
        this(fClient, session, null, 0, null, autoCommit, statementSession, sqls);
    }

    private void prepare(ConnectionSession s, boolean createParams) {
        if (fetchSize > 0) {
            isQuery = true;
        }
    }

    @Override
    public boolean isQuery() {
        return isQuery;
    }

    @Override
    public ArrayList<ParameterInterface> getParameters() {
        return parameters;
    }

    private void prepareIfRequired() {
        if (session.getLastReconnect() != created) {
            // in this case we need to prepare again in every case
            id = Integer.MIN_VALUE;
        }
        session.checkClosed();
        if (id <= session.getCurrentId()) {
            // object is too old - we need to prepare again
            prepare(session, false);
        }
    }

    @Override
    public ResultInterface getMetaData() {
        return null;
    }

    @Override
    public ResultInterface executeQuery(int maxRows) throws SQLException {
        checkParameters();
        synchronized (session) {
            int objectId = session.getNextId();
            ResultRemote result = null;
            prepareIfRequired();
            try {
                ResultTransfer transfer = new ResultTransfer(null, null);
                result = new ResultRemote(fClient, SessionFactory.createExecuteSession(), transfer, sql, objectId,
                        fetchSize, true, readModel, false, null);
                isQuery = result.isQuery();
                if (!isQuery() && result.getRowCount() > 0) {
                    throw JdbcException.get(SQLErrorCode.METHOD_ONLY_ALLOWED_FOR_QUERY, "sql:" + sql);
                }
            } catch (IOException e) {
                session.removeServer(e);
            }
            return result;
        }
    }

    private String getTableName(String sql) {
        return null; // To change body of created methods use File | Settings | File
                     // Templates.
    }

    private List<Field> getFileds(String sql) {
        return null; // To change body of created methods use File | Settings | File
                     // Templates.
    }

    @Override
    public int executeUpdate() throws SQLException {
        checkParameters();
        synchronized (session) {
            prepareIfRequired();
            ResultRemote result = null;
            String tablename = getTableName(sql);
            ResultTransfer transfer = new ResultTransfer(null, tablename);
            try {
                result = new ResultRemote(fClient, statementSession, transfer, sql, readModel);
                result.next();
                isQuery = result.isQuery();
                if (isQuery()) {
                    throw JdbcException.get(SQLErrorCode.METHOD_NOT_ALLOWED_FOR_QUERY, "sql:" + sql);
                }
                Value[] values = result.currentRow();
                if (values == null || values.length == 0) {
                    return 0;
                }
                if (values[0] instanceof ValueInt) {
                    return ((ValueInt) values[0]).getInt();
                }

            } catch (IOException e) {
                session.removeServer(e);
            }
            return transfer.getCounts();
        }
    }

    @Override
    public int executeTransaction() throws SQLException {
        checkParameters();
        synchronized (session) {
            prepareIfRequired();
            ResultRemote result = null;
            ResultTransfer transfer = new ResultTransfer(null, null);
            try {
                result = new ResultRemote(fClient, statementSession, transfer, sqls, true);
                result.next();
                isQuery = result.isQuery();
                if (isQuery()) {
                    throw JdbcException.get(SQLErrorCode.METHOD_NOT_ALLOWED_FOR_QUERY, "sql:" + sql);
                }
                Value[] values = result.currentRow();
                if (values == null || values.length == 0) {
                    return 0;
                }
                if (values[0] instanceof ValueInt) {
                    return ((ValueInt) values[0]).getInt();
                }

            } catch (IOException e) {
                session.removeServer(e);
            }
            return transfer.getCounts();
        }
    }

    private void checkParameters() {
        for (ParameterInterface p : parameters) {
            p.checkSet();
        }
    }

    @Override
    public void close() {
        if (session == null || session.isClosed()) {
            return;
        }
        session = null;
        try {
            for (ParameterInterface p : parameters) {
                Value v = p.getParamValue();
                if (v != null) {
                    v.close();
                }
            }
        } catch (JdbcException e) {
            log.error("close", e);
        }
        parameters.clear();
    }

    /**
     * Cancel this current statement.
     */
    @Override
    public void cancel() {
        session.cancelStatement(id);
    }

    @Override
    public String toString() {
        return sql;
    }

    @Override
    public int getCommandType() {
        return UNKNOWN;
    }
}