com.alibaba.wasp.jdbc.JdbcConnection.java Source code

Java tutorial

Introduction

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

Source

/**
 * Copyright The Apache Software Foundation
 *
 * 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;

import com.alibaba.wasp.FConstants;
import com.alibaba.wasp.SQLErrorCode;
import com.alibaba.wasp.client.FClient;
import com.alibaba.wasp.jdbc.command.CommandInterface;
import com.alibaba.wasp.jdbc.result.JdbcDatabaseMetaData;
import com.alibaba.wasp.jdbc.value.Value;
import com.alibaba.wasp.session.ExecuteSession;
import com.alibaba.wasp.session.SessionFactory;
import com.alibaba.wasp.session.SessionInterface;
import com.alibaba.wasp.util.StringUtils;
import com.alibaba.wasp.util.Utils;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;

/**
 * <p>
 * Represents a connection (session) to wasp cluster.
 * </p>
 * <p>
 * Thread safety: the connection is thread-safe, because access is synchronized.
 * However, for compatibility with other wasp cluster, a connection should only
 * be used in one thread at any time.
 * </p>
 */
public class JdbcConnection implements Connection {

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

    private static boolean keepOpenStackTrace = false;

    private final String url;
    private final String user;
    private int holdability = 1;
    private SessionInterface session;

    private final FClient fClient;
    private final Configuration conf;

    private Statement executingStatement;
    private final CloseWatcher watcher;
    private int queryTimeoutCache = -1;
    private Properties properties;
    private boolean autoCommit;

    /**
     * Constructor.
     * 
     * @param url
     * 
     * @param info
     * 
     * @throws java.sql.SQLException
     */
    public JdbcConnection(String url, Properties info) throws SQLException {
        this(new ConnectionInfo(url, info), Utils.convertPropertiesToConfiguration(info));
        this.properties = info;
    }

    /**
     * Wasp's JDBC connection.
     *
     * @param ci
     * @throws java.sql.SQLException
     */
    private JdbcConnection(ConnectionInfo ci, Configuration conf) throws SQLException {
        try {
            // this will return an embedded or server connection
            session = SessionFactory.createConnectionSession(ci);
            this.user = ci.getUserName();
            log.info("Connection conn = DriverManager.getConnection("
                    + StringUtils.quoteJavaString(ci.getOriginalURL()) + ", " + StringUtils.quoteJavaString(user)
                    + ", \"\");");
            this.url = ci.getURL();
            closeOld();
            watcher = CloseWatcher.register(this, session, keepOpenStackTrace);
            this.conf = conf;
            this.fClient = new FClient(this.conf);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    public JdbcConnection(JdbcConnection conn) throws SQLException {
        this(conn.getURL(), conn.getClientInfo());
    }

    private void closeOld() {
        while (true) {
            CloseWatcher w = CloseWatcher.pollUnclosed();
            if (w == null) {
                break;
            }
            try {
                w.getCloseable().close();
            } catch (Exception e) {
                log.error("closing session", e);
            }
        }
    }

    /**
     * Creates a new statement.
     *
     * @return the new statement
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public Statement createStatement() throws SQLException {
        try {
            checkClosed();
            return new JdbcStatement(this, ResultSet.TYPE_FORWARD_ONLY, FConstants.DEFAULT_RESULT_SET_CONCURRENCY,
                    false);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Creates a statement with the specified result set type and concurrency.
     *
     * @param resultSetType
     *          the result set type (ResultSet.TYPE_*)
     * @param resultSetConcurrency
     *          the concurrency (ResultSet.CONCUR_*)
     * @return the statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the result set type or concurrency
     *           are not supported
     */
    @Override
    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
        try {
            checkTypeConcurrency(resultSetType, resultSetConcurrency);
            checkClosed();
            return new JdbcStatement(this, resultSetType, resultSetConcurrency, false);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Creates a statement with the specified result set type, concurrency, and
     * holdability.
     *
     * @param resultSetType
     *          the result set type (ResultSet.TYPE_*)
     * @param resultSetConcurrency
     *          the concurrency (ResultSet.CONCUR_*)
     * @param resultSetHoldability
     *          the holdability (ResultSet.HOLD* / CLOSE*)
     * @return the statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the result set type, concurrency,
     *           or holdability are not supported
     */
    @Override
    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability)
            throws SQLException {
        try {
            checkTypeConcurrency(resultSetType, resultSetConcurrency);
            checkHoldability(resultSetHoldability);
            checkClosed();
            return new JdbcStatement(this, resultSetType, resultSetConcurrency, false);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Creates a new prepared statement.
     *
     * @param sql
     *          the SQL statement
     * @return the prepared statement
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        try {
            checkClosed();
            return new JdbcPreparedStatement(this, sql, ResultSet.TYPE_FORWARD_ONLY,
                    FConstants.DEFAULT_RESULT_SET_CONCURRENCY, false);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Prepare a statement that will automatically close when the result set is
     * closed. This method is used to retrieve database meta data.
     *
     * @param sql
     *          the SQL statement
     * @return the prepared statement
     */
    PreparedStatement prepareAutoCloseStatement(String sql) throws SQLException {
        try {
            checkClosed();
            return new JdbcPreparedStatement(this, sql, ResultSet.TYPE_FORWARD_ONLY,
                    FConstants.DEFAULT_RESULT_SET_CONCURRENCY, true);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Gets the database meta data for this database.
     *
     * @return the database meta data
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public DatabaseMetaData getMetaData() throws SQLException {
        try {
            checkClosed();
            return new JdbcDatabaseMetaData(this);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * INTERNAL
     */
    public SessionInterface getSession() {
        return session;
    }

    /**
     * Closes this connection. All open statements, prepared statements and result
     * sets that where created by this connection become invalid after calling
     * this method. If there is an uncommitted transaction, it will be rolled
     * back.
     */
    @Override
    public synchronized void close() throws SQLException {
        try {
            if (session == null) {
                return;
            }
            CloseWatcher.unregister(watcher);
            session.close();
            if (executingStatement != null) {
                try {
                    executingStatement.close();
                } catch (NullPointerException e) {
                    // ignore
                }
            }
            synchronized (session) {
                try {
                    if (!session.isClosed()) {
                        session.close();
                    }
                } finally {
                    session = null;
                }
            }
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    @Override
    public void setAutoCommit(boolean autoCommit) throws SQLException {
        this.autoCommit = autoCommit;
    }

    /**
     * Gets the current setting for auto commit.
     *
     * @return true for on, false for off
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public synchronized boolean getAutoCommit() throws SQLException {
        return this.autoCommit;
    }

    /**
     *
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public synchronized void commit() throws SQLException {
        autoCommit = true;
    }

    /**
     * unsupported rollback
     *
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public synchronized void rollback() throws SQLException {
        throw JdbcException.getUnsupportedException("rollback unsupported");
    }

    /**
     * Returns true if this connection has been closed.
     *
     * @return true if close was called
     */
    @Override
    public boolean isClosed() throws SQLException {
        return session == null || session.isClosed();
    }

    /**
     * Translates a SQL statement into the database grammar.
     *
     * @param sql
     *          the SQL statement with or without JDBC escape sequences
     * @return the translated statement
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public String nativeSQL(String sql) throws SQLException {
        try {
            checkClosed();
            return sql;
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * According to the JDBC specs, this setting is only a hint to the database to
     * enable optimizations - it does not cause writes to be prohibited.
     *
     * @param readOnly
     *          ignored
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public void setReadOnly(boolean readOnly) throws SQLException {
        checkClosed();
    }

    /**
     * Returns true if the database is read-only.
     *
     * @return if the database is read-only
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public boolean isReadOnly() throws SQLException {
        checkClosed();
        return false;
    }

    /**
     * Set the default catalog name. This call is ignored.
     *
     * @param catalog
     *          ignored
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public void setCatalog(String catalog) throws SQLException {
        throw JdbcException.getUnsupportedException("setCatalog unsupported");
    }

    /**
     * Gets the current catalog name.
     *
     * @return the catalog name
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public String getCatalog() throws SQLException {
        throw JdbcException.getUnsupportedException("getCatalog unsupported");
    }

    /**
     * Gets the first warning reported by calls on this object.
     *
     * @return null
     */
    @Override
    public SQLWarning getWarnings() throws SQLException {
        throw JdbcException.getUnsupportedException("getWarnings unsupported");
    }

    /**
     * Clears all warnings.
     */
    @Override
    public void clearWarnings() throws SQLException {
        throw JdbcException.getUnsupportedException("clearWarnings unsupported");
    }

    /**
     * Creates a prepared statement with the specified result set type and
     * concurrency.
     *
     * @param sql
     *          the SQL statement
     * @param resultSetType
     *          the result set type (ResultSet.TYPE_*)
     * @param resultSetConcurrency
     *          the concurrency (ResultSet.CONCUR_*)
     * @return the prepared statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the result set type or concurrency
     *           are not supported
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
            throws SQLException {
        try {
            checkTypeConcurrency(resultSetType, resultSetConcurrency);
            checkClosed();
            return new JdbcPreparedStatement(this, sql, resultSetType, resultSetConcurrency, false);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    @Override
    public void setTransactionIsolation(int level) throws SQLException {
        // default wasp level
    }

    public void setQueryTimeout(int seconds) throws SQLException {
        queryTimeoutCache = seconds;
    }

    public int getQueryTimeout() throws SQLException {
        return queryTimeoutCache;
    }

    /**
     * Returns the current transaction isolation level.
     *
     * @return the isolation level.
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public int getTransactionIsolation() throws SQLException {
        // default wasp level. the return value no needed.
        return 0;
    }

    /**
     * Changes the current result set holdability.
     *
     * @param holdability
     *          ResultSet.HOLD_CURSORS_OVER_COMMIT or
     *          ResultSet.CLOSE_CURSORS_AT_COMMIT;
     * @throws java.sql.SQLException
     *           if the connection is closed or the holdability is not supported
     */
    @Override
    public void setHoldability(int holdability) throws SQLException {
        try {
            checkClosed();
            checkHoldability(holdability);
            this.holdability = holdability;
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Returns the current result set holdability.
     *
     * @return the holdability
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public int getHoldability() throws SQLException {
        try {
            checkClosed();
            return holdability;
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Gets the type map.
     *
     * @return null
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public Map<String, Class<?>> getTypeMap() throws SQLException {
        try {
            checkClosed();
            return null;
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * [Partially supported] Sets the type map. This is only supported if the map
     * is empty or null.
     */
    @Override
    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
        try {
            checkMap(map);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * unsupported
     *
     * @param sql
     *          the SQL statement
     * @return the callable statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the statement is not valid
     */
    @Override
    public CallableStatement prepareCall(String sql) throws SQLException {
        throw JdbcException.getUnsupportedException("prepareCall unsupported");
    }

    /**
     * unsupported
     *
     * @param sql
     *          the SQL statement
     * @param resultSetType
     *          the result set type (ResultSet.TYPE_*)
     * @param resultSetConcurrency
     *          the concurrency (ResultSet.CONCUR_*)
     * @return the callable statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the result set type or concurrency
     *           are not supported
     */
    @Override
    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
            throws SQLException {
        throw JdbcException.getUnsupportedException("prepareCall unsupported");
    }

    /**
     * unsupported
     *
     * @param sql
     *          the SQL statement
     * @param resultSetType
     *          the result set type (ResultSet.TYPE_*)
     * @param resultSetConcurrency
     *          the concurrency (ResultSet.CONCUR_*)
     * @param resultSetHoldability
     *          the holdability (ResultSet.HOLD* / CLOSE*)
     * @return the callable statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the result set type, concurrency,
     *           or holdability are not supported
     */
    @Override
    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
            int resultSetHoldability) throws SQLException {
        throw JdbcException.getUnsupportedException("prepareCall unsupported");
    }

    /**
     * Creates a new unnamed savepoint.
     *
     * @return the new savepoint
     */
    @Override
    public Savepoint setSavepoint() throws SQLException {
        throw JdbcException.getUnsupportedException("setSavePoint unsupported");
    }

    /**
     * Creates a new named savepoint.
     *
     * @param name
     *          the savepoint name
     * @return the new savepoint
     */
    @Override
    public Savepoint setSavepoint(String name) throws SQLException {
        throw JdbcException.getUnsupportedException("setSavePoint unsupported");
    }

    /**
     * Rolls back to a savepoint.
     *
     * @param savepoint
     *          the savepoint
     */
    @Override
    public void rollback(Savepoint savepoint) throws SQLException {
        throw JdbcException.getUnsupportedException("rollback unsupported");
    }

    /**
     * Releases a savepoint.
     *
     * @param savepoint
     *          the savepoint to release
     */
    @Override
    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
        throw JdbcException.getUnsupportedException("releaseSavePoint unsupported");
    }

    /**
     * Creates a prepared statement with the specified result set type,
     * concurrency, and holdability.
     *
     * @param sql
     *          the SQL statement
     * @param resultSetType
     *          the result set type (ResultSet.TYPE_*)
     * @param resultSetConcurrency
     *          the concurrency (ResultSet.CONCUR_*)
     * @param resultSetHoldability
     *          the holdability (ResultSet.HOLD* / CLOSE*)
     * @return the prepared statement
     * @throws java.sql.SQLException
     *           if the connection is closed or the result set type, concurrency,
     *           or holdability are not supported
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
            int resultSetHoldability) throws SQLException {
        try {
            checkTypeConcurrency(resultSetType, resultSetConcurrency);
            checkHoldability(resultSetHoldability);
            checkClosed();
            return new JdbcPreparedStatement(this, sql, resultSetType, resultSetConcurrency, false);
        } catch (Exception e) {
            throw Logger.logAndConvert(log, e);
        }
    }

    /**
     * Creates a new prepared statement. This method just calls
     * prepareStatement(String sql) internally. The method getGeneratedKeys only
     * supports one column.
     *
     * @param sql
     *          the SQL statement
     * @param autoGeneratedKeys
     *          ignored
     * @return the prepared statement
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
        return prepareStatement(sql);
    }

    /**
     * Creates a new prepared statement. This method just calls
     * prepareStatement(String sql) internally. The method getGeneratedKeys only
     * supports one column.
     *
     * @param sql
     *          the SQL statement
     * @param columnIndexes
     *          ignored
     * @return the prepared statement
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
        return prepareStatement(sql);
    }

    /**
     * Creates a new prepared statement. This method just calls
     * prepareStatement(String sql) internally. The method getGeneratedKeys only
     * supports one column.
     *
     * @param sql
     *          the SQL statement
     * @param columnNames
     *          ignored
     * @return the prepared statement
     * @throws java.sql.SQLException
     *           if the connection is closed
     */
    @Override
    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
        return prepareStatement(sql);
    }

    @Override
    public Clob createClob() throws SQLException {
        throw JdbcException.getUnsupportedException("createClob unsupported");
    }

    @Override
    public Blob createBlob() throws SQLException {
        throw JdbcException.getUnsupportedException("createBlob unsupported");
    }

    @Override
    public NClob createNClob() throws SQLException {
        throw JdbcException.getUnsupportedException("createNClob unsupported");
    }

    private void checkTypeConcurrency(int resultSetType, int resultSetConcurrency) {
        switch (resultSetType) {
        case ResultSet.TYPE_FORWARD_ONLY:
        case ResultSet.TYPE_SCROLL_INSENSITIVE:
        case ResultSet.TYPE_SCROLL_SENSITIVE:
            break;
        default:
            throw JdbcException.getInvalidValueException("resultSetType", resultSetType);
        }
        switch (resultSetConcurrency) {
        case ResultSet.CONCUR_READ_ONLY:
        case ResultSet.CONCUR_UPDATABLE:
            break;
        default:
            throw JdbcException.getInvalidValueException("resultSetConcurrency", resultSetConcurrency);
        }
    }

    private void checkHoldability(int resultSetHoldability) {
        if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT
                && resultSetHoldability != ResultSet.CLOSE_CURSORS_AT_COMMIT) {
            throw JdbcException.getInvalidValueException("resultSetHoldability", resultSetHoldability);
        }
    }

    /**
     * Check if this connection is closed. The next operation is a read request.
     *
     * @throws JdbcException
     *           if the connection or session is closed
     */
    public void checkClosed() {
        checkClosed(false);
    }

    /**
     * Check if this connection is closed.
     *
     * @param write
     *          if the next operation is possibly writing
     * @throws JdbcException
     *           if the connection or session is closed
     */
    protected void checkClosed(boolean write) {
        if (session == null) {
            throw JdbcException.get(SQLErrorCode.OBJECT_CLOSED);
        }
        if (session.isClosed()) {
            throw JdbcException.get(SQLErrorCode.DATABASE_CALLED_AT_SHUTDOWN);
        }
    }

    public String getURL() {
        checkClosed();
        return url;
    }

    public String getUser() {
        checkClosed();
        return user;
    }

    /**
     * 
     */
    public void setExecutingStatement(Statement stat) {
        executingStatement = stat;
    }

    /**
     * [Not supported] Create a new empty SQLXML object.
     */
    @Override
    public SQLXML createSQLXML() throws SQLException {
        throw JdbcException.getUnsupportedException("createSQLXML unsupported");
    }

    /**
     * [Not supported] Create a new empty Array object.
     */
    @Override
    public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
        throw JdbcException.getUnsupportedException("createArrayOf unsupported");
    }

    /**
     * [Not supported] Create a new empty Struct object.
     */
    @Override
    public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
        throw JdbcException.getUnsupportedException("createStruct unsupported");
    }

    /**
     * Returns true if this connection is still valid.
     * 
     * @param timeout
     *          the number of seconds to wait for the database to respond
     *          (ignored)
     * @return true if the connection is valid.
     */
    @Override
    public synchronized boolean isValid(int timeout) {
        try {
            if (session == null || session.isClosed()) {
                return false;
            }
            // force a network round trip (if networked)
            getTransactionIsolation();
            return true;
        } catch (Exception e) {
            // this method doesn't throw an exception, but it logs it
            Logger.logAndConvert(log, e);
            return false;
        }
    }

    /**
     * [Not supported] Set a client property.
     */
    @Override
    public void setClientInfo(String name, String value) throws SQLClientInfoException {
        this.properties.setProperty(name, value);
        // throw new SQLClientInfoException();
    }

    /**
     * [Not supported] Set the client properties.
     */
    @Override
    public void setClientInfo(Properties properties) throws SQLClientInfoException {
        this.properties.putAll(properties);
        // throw new SQLClientInfoException();
    }

    /**
     * [Not supported] Get the client properties.
     */
    @Override
    public Properties getClientInfo() throws SQLClientInfoException {
        return this.properties;
    }

    /**
     * [Not supported] Set a client property.
     */
    @Override
    public String getClientInfo(String name) throws SQLException {
        return this.properties.getProperty(name);
    }

    /**
     * [Not supported] Return an object of this class if possible.
     * 
     * @param iface
     *          the class
     */
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        throw JdbcException.getUnsupportedException("unwrap unsupported");
    }

    /**
     * [Not supported] Checks if unwrap can return an object of this class.
     * 
     * @param iface
     *          the class
     */
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        throw JdbcException.getUnsupportedException("isWrapperFor unsupported");
    }

    private static void checkMap(Map<String, Class<?>> map) {
        if (map != null && map.size() > 0) {
            throw JdbcException.getUnsupportedException("map.size > 0");
        }
    }

    public String toString() {
        return "Conn : url=" + url + " user=" + user;
    }

    public CommandInterface prepareCommand(String sql, int fetchSize, ExecuteSession statementSession) {
        String readModel = properties.getProperty(FConstants.READ_MODEL);
        return session.prepareCommand(fClient, sql, fetchSize, Utils.getReadModel(readModel), autoCommit,
                statementSession);
    }

    public CommandInterface prepareCommand(List<String> sqls, ExecuteSession statementSession) {
        String readModel = properties.getProperty(FConstants.READ_MODEL);
        return session.prepareCommand(fClient, sqls, autoCommit, statementSession);
    }

    public Object convertToDefaultObject(Value v) {
        return v.getObject();
    }

    public Configuration getConf() {
        return this.conf;
    }

    /**
     * INTERNAL. Called after executing a command that could have written
     * something.
     */
    protected void afterWriting() {
        if (session != null) {
            session.afterWriting();
        }
    }

    public void setSchema(String schema) throws SQLException {
        throw new NotImplementedException();
    }

    public String getSchema() throws SQLException {
        throw new NotImplementedException();
    }

    public void abort(Executor executor) throws SQLException {
        throw new NotImplementedException();
    }

    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
        throw new NotImplementedException();
    }

    public int getNetworkTimeout() throws SQLException {
        throw new NotImplementedException();
    }

}